有的时候,需要了解一个目录及其子目录的层次结构,比方说在找东西的时候,不记得东西放在什么目录下了,或者忘了当初在什么位置创建了一个目录,再比方说看代码的时候,想要了解整个project的代码是怎么进行目录划分的,系统里有查看进程树的命令,但是没有查看目录树的命令,ls命令没有这个功能,于是作者便写了个小程序来完成这个工作。小程序只适用于linux平台,windows平台的版本有心的朋友可以自行修改一下实现。
下面这张图便是作者用小程序打印出来的系统里的一个目录树:
作者是参考进程树的输出样式来设计的目录树的输出样式。在这张图里,--和|-用来表示树的分支,树的结点的各个子结点各在一行并且水平位置一致。
来说一下这个程序的设计思路,要打印目录树,必然离不了对目录树的遍历操作,这里采用后根遍历来访问目录树,一边访问各级目录,一边进行目录树的绘制,绘制图形的时候按行进行绘制。程序的难点在于按行进行绘制,如上图所见,图的一行里除了有目录名称和表示树的分支的--和|-之外,还有大量的空白和单一的|以及换行,为了完成工作,我们需要记住由根目录(树的根结点)到当前访问到的目录(树的结点)的路径,依次访问路径上的结点,进行图的行的绘制。代码见下方。
import os, sys
class dirattrs:
firstchld = False
lastchld = False
allchlddrawed = False
def __init__(self, dirpath):
self.path = dirpath
self.name = os.path.basename(dirpath)
def setfirstchld(self):
self.firstchld = True
def setlastchld(self):
self.lastchld = True
def setallchlddrawed(self):
self.allchlddrawed = True
def dirtraverse(dirpath):
dirchain = []
dirmap = "";
def blanks(n):
return "".join([" " for i in range(n)])
def draw():
nonlocal dirmap
for i, d in enumerate(dirchain):
if d is dirchain[-1]:
dirmap += d.name
if d.lastchld is True:
dirchain[i - 1].setallchlddrawed()
else:
if dirchain[-1].firstchld is not True:
if not d.allchlddrawed:
if dirchain[i + 1] is dirchain[-1]:
dirmap += blanks(len(d.name)) + "|-"
else:
dirmap += blanks(len(d.name)) + "| "
else:
dirmap += blanks(len(d.name) + 2)
else:
if d is dirchain[-2]:
dirmap += "--"
def traverse(dirobj):
nonlocal dirmap
dirchain.append(dirobj)
draw()
subdirs = []
for chldfile in os.listdir(dirobj.path):
chldfilepath = dirobj.path + "/" + chldfile
if os.path.isdir(chldfilepath):
subdirs.append(dirattrs(chldfilepath))
if not subdirs:
dirmap += "\n"
dirchain.pop()
return
subdirs[0].setfirstchld()
subdirs[-1].setlastchld()
for d in subdirs:
traverse(d)
dirchain.pop()
dirpath = os.path.abspath(dirpath)
traverse(dirattrs(dirpath))
return dirmap
if __name__ == "__main__":
print(dirtraverse(sys.argv[1]))
标签:self,打印,dirpath,dirmap,dirchain,目录,def
From: https://blog.csdn.net/weixin_40756114/article/details/137264301