Python: 生成目录树
前言
一直觉得windows下的tree
命令生成的目录树方便又美观,无奈微软并不会提供tree
命令的实现源码,于是就拿Python撸了一个出来。
效果请看下图吧,代码也在下文中。如果你想了解实现细节,我在下文中也有一些简单的解释。
效果
下图是一个Intellij IDEA工程的目录树(不同字体可能显示略有差异):
├─.idea
│ ├─inspectionProfiles
│ ├─misc.xml
│ ├─modules.xml
│ └─workspace.xml
├─out
│ └─production
│ ├─TempJava
│ │ ├─A.class
│ │ ├─B.class
│ │ ├─Main$HeapSort.class
│ │ ├─Main$LexicalOrder.class
│ │ ├─Main$ListNode.class
│ │ ├─Main$TreeNode.class
│ │ ├─Main.class
│ │ ├─Solution.class
│ │ ├─Temp.class
│ │ └─Test.class
│ └─.DS_Store
├─src
│ ├─Main.java
│ ├─Solution.java
│ ├─Temp.java
│ └─Test.java
├─.DS_Store
└─TempJava.iml
代码
import os
import os.path
BRANCH = '├─'
LAST_BRANCH = '└─'
TAB = '│ '
EMPTY_TAB = ' '
def get_dir_list(path, placeholder=''):
folder_list = [folder for folder in os.listdir(path) if os.path.isdir(os.path.join(path, folder))]
file_list = [file for file in os.listdir(path) if os.path.isfile(os.path.join(path, file))]
result = ''
for folder in folder_list[:-1]:
result += placeholder + BRANCH + folder + '\n'
result += get_dir_list(os.path.join(path, folder), placeholder + TAB)
if folder_list:
result += placeholder + (BRANCH if file_list else LAST_BRANCH) + folder_list[-1] + '\n'
result += get_dir_list(os.path.join(path, folder_list[-1]), placeholder + (TAB if file_list else EMPTY_TAB))
for file in file_list[:-1]:
result += placeholder + BRANCH + file + '\n'
if file_list:
result += placeholder + LAST_BRANCH + file_list[-1] + '\n'
return result
if __name__ == '__main__':
print(get_dir_list('./TempJava'))
get_dir_list()
的参数为需要生成目录树的根目录的路径,其返回值是一个字符串,你可以直接打印出来,或保存到文件中。
实现细节
目录树的生成是一个递归调用,get_dir_list()
每次调用都是在遍历当前文件夹下的子文件夹和文件,当遇到子文件夹时就递归调用get_dir_list()
,然后将其返回结果加入到当前结果中。
为了实现不同目录层级缩进的效果,我们需要在对应行前加入一些“占位符”。再仔细想想可以发现对于同一层级,占位符都是一致的,所以我们可以把占位符当作递归的参数,每次递归都增加一些参数。
看上图可以发现,每一次增加的占位符基本上都是'│ '
;但也存在例外情况,如上图中out文件夹下,遍历production文件夹时,其最后一个占位符就是' '
,原因是什么呢?因为out文件夹下仅有production文件夹,导致其不必继续输出其他分支(和其他的文件夹对比看看)。所以在遍历到最后一个子文件夹时,需要判断是否存在子文件,如存在,则使用'│ '
,否则使用' '
。
还有一个需要注意的地方是,对于最后一个子文件夹/文件,其应以'└─'
开头,而非'├─'
。这个其实很容易实现,看代码就明白啦,主要就是list[:-1]
这个的应用。
大概细节就是这样,如果你有更好的实现,还请不吝赐教~
本文的代码也不能打出10万行的
提示:
OSError: [Errno 34] Result too large
只打目录不打文件20万行打印成功了
打印目录加文件失败了
还是上面那个错误
这个应该是数组大小或list的长度超出了python的限制,解决方法一个是在执行过程中就定时写list然后清空继续,不过改造难度比较大;二个就是分批次打印目录咯,就是每次只打印一个子目录之类的。
哈哈你的需求太奇特
我在mac下使用的tree命令
超过10w行的以文件形式输出会有乱码
请问你知道怎么解决吗?
提示发言过于频繁 总是发不出来
抱歉,对于自带的命令不太清楚哦...
这里是对评论的来源IP作了限制的,间隔是10分钟
你好,请问打印的时候出现没有权限问题怎么办?
你应该是在Windows下打印C盘的某些目录吧?可能是Windows权限管理的问题。你可以试试用管理员身份打开命令行cmd,然后运行python xx.py命令。
Linux下也有tree命令吧,一直在用,apt install tree
哈哈,确实Linux上有,这个算体验重复造轮子的乐趣啦