打印目录树

       有的时候,需要了解一个目录及其子目录的层次结构,比方说在找东西的时候,不记得东西放在什么目录下了,或者忘了当初在什么位置创建了一个目录,再比方说看代码的时候,想要了解整个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]))

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__空无一人__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值