创建 Python 目录树生成器

2025年3月17日 | 阅读 12 分钟

在本教程中,我们将学习用于 Python 命令行中的目录树生成器工具。Python 开发人员应具备使用命令行界面 (CLI) 创建用户友好型应用程序的技能。此技能有助于创建工具,以自动化和加速我们工作环境中的任务。该应用程序从命令行运行时将接受一个目录路径作为参数,并在屏幕上显示一个目录树图。还将提供其他选项来自定义输出。

Python 中的目录树生成器工具

本教程将教我们构建一个命令行工具,以树状图的形式列出目录或文件夹的内容。有多种解决方案可实现此任务,例如在大多数操作系统上都可用的 tree 命令。还有几种可用的工具,例如 treelib、dirtriex 等。但是,我们将创建自己的解决方案以获得更好的理解。

我们的目录树生成器将拥有一个用户友好的 CLI。它还具有独特的功能,例如在我们的终端上显示包含目录内容的树状图。

这个项目将由一个命令行应用程序组成,我们需要提供目录作为路径。我们将遍历其内部结构并生成一个树状图,列出目录的内容。在深入研究解决方案之前,让我们看看问题。

项目布局

为了创建目录结构,我们需要创建一些模块和包;我们将为项目提供一个连贯的 Python 应用程序布局。

解决方案概述

生成一个准确反映文件系统中目录内容的树状图表面上看起来很简单,但实际上涉及大量的复杂性。遍历目录并以用户友好的方式呈现信息需要仔细考虑和关注细节。

在目录中查找特定文件的任务可以通过递归来实现。想象一下我们正在主目录中,使用文件管理器搜索文件。如果文件没有立即找到,我们可以导航到子目录并重复该过程,打开每个子目录以检查文件。这个过程分为以下步骤:

  1. 从主目录开始
  2. 检查文件
  3. 如果未找到文件,则进入子目录

重复步骤 2 和 3,直到找到文件或搜索完所有子目录。

总之,当我们处理目录及其内容时,我们需要遵循递归方法。

这是本教程中将使用的方法。通常,将采取以下步骤:

  1. 识别文件系统中目录的路径。
  2. 递归遍历目录及其子目录
  3. 获取其所有条目(目录和文件)的列表
  4. 如果目录包含子目录,则从步骤二开始重复该过程。

在第一步中,我们需要在命令行提供目录路径。我们可以使用标准库中的 Python argparse 模块来完成此操作。

在第二步中,我们将使用 pathlib 库,它将提供多种工具来管理和表示文件系统路径。我们还将使用常规的 Python 列表来存储目录结构中的条目列表。

组织代码

单一职责原则可用于组织代码。我们的目录树生成器应用程序有三个职责:

  1. 提供 CLI
  2. 遍历根目录并构建树状图
  3. 显示树状图

CLI 相关的代码将写入 cli.py。我们将编写高级的 DirectoryTree 类来生成和显示树状图。可执行代码将在 main() 函数中。该类将有一个名为 .generate() 的方法,负责生成和显示目录树状图。

将创建一个低级别的 _TreeGenerator 类来遍历目录结构并构建构成树状图的条目列表。该类将有一个名为 .build_tree() 的方法来执行此操作。

树状图将包含三个组件。

  1. 头部 - 它将提供根目录表示
  2. 主体 - 它将提供目录内容表示。

树状图将有一个头部表示,它将由根目录的名称和一个额外的管道(│)字符组成,用于连接树的头部和主体。

树主体表示将包含根目录的名称以及一个额外的管道 (|) 字符,用于连接树和主体。

  • 前缀字符串将用于提供适当的间距,以反映树状图中条目在目录结构中的位置。
  • 将使用一个字符将当前子目录或文件与其父目录连接到树状图中。
  • 当前子目录或文件的名称。

组合的目录树结构将如下所示 -

Create a Python Directory Tree Generator

树生成器类的 build_tree() 方法将返回构成目录树状图的所有条目的列表。要显示该图,需要调用目录树对象的 generate() 方法。

我们的树目录不需要任何外部库。现在我们将按照几个步骤来构建命令行界面。

步骤 - 1:设置项目结构

在第一步中,我们需要为目录树生成器项目设置一个易于理解的应用程序布局。现在,我们将在文件系统上创建一个名为 mytree_project/ 的新目录。在该目录中,我们需要创建两个空文件。

  • README.md
  • tree.py

接下来,我们将创建名为 mytree/ 的子目录,其中包含以下空文件。

  • my_tree.py
  • __init__.py
  • cli.py

现在,我们的项目目录结构如下所示。

此外,我们还需要进行额外的设置。我们在 __init__.py 文件中添加以下内容。

Python 使用 __init__.py 文件将普通目录转换为包。在本项目中,这些包包含 my_tree.py 和 cli.py 等模块。包和模块是用于组织和构建 Python 代码的工具。它们允许将代码分组为更小、更易于管理的单元,从而更易于重用和共享。Python 标准库也采用这种组织方法,将各种模块分组到包中。这为开发人员提供了对预先存在的代码的轻松访问,用于常用任务。

最后,我们将创建示例目录来测试应用程序并确保其正常工作。其结构类似于 Python 项目的通用布局。我们将在整个步骤中使用示例目录结构来测试目录树生成器工具。

步骤 - 2:在 Python 中生成目录树状图

到目前为止,我们已经设置了示例项目的布局。在本节中,我们将编写项目主要功能的代码。换句话说,我们将编写代码以从输入目录路径生成完整的目录树状图。让我们理解以下示例。

示例 -

解释 -

在上面的代码中,我们导入了两个模块:os 和 pathlib。os 模块提供了一种与操作系统交互的方式,而 pathlib 模块提供了一种面向对象的方式来处理文件路径。

我们定义了三个变量:PIPE、ELBOW 和 TEE。这些变量分别包含字符串字符“│”、“└──”和“├──”。这些字符用于在显示目录结构时创建树状结构。

我们还定义了 PIPE_PREFIX 和 SPACE_PREFIX 变量。这些变量分别包含字符串“│ ”和“ ”。这些字符串用作树状结构中行的前缀,用于指示结构中目录或文件的级别。

上面的代码构建了一个目录或文件系统的树状结构,其中 PIPE、ELBOW 和 TEE 用于指示级别,PIPE_PREFIX 和 SPACE_PREFIX 用于创建适当的可视化表示。尽管代码不执行任何操作,但我们正在准备必要的变量和对象,以用于可以遍历目录结构并以树状格式显示它的函数。

创建高级 DirectoryClass

在本节中,我们将定义一个类来创建目录树状图并将其显示在屏幕上。让我们理解以下代码。

示例 -

此代码定义了一个名为 DirectoryTreeGenerator 的类。该类有一个 __init__() 方法,该方法接受一个参数 root_dir,它表示树结构的根目录。

在 __init__() 方法中,创建了另一个类 _TreeGenerator 的实例,并将其 root_dir 作为参数传递。然后,此实例被分配给实例变量 self._generator。

该类还有一个名为 generate 的方法,用于生成树结构。此方法使用 self._generator 实例调用 build_tree() 方法。build_tree() 方法返回一个包含树结构的迭代器,然后将其分配给变量 tree。

generate 方法随后使用 for 循环遍历 tree 变量并打印每个条目。它会将树结构打印到控制台。在下一节中,我们将创建 _TreeGenerator 类。

创建 _TreeGenerator 类

现在,我们将创建 _TreeGenerator 类,它将遍历文件系统并生成目录树状图。

示例 -

解释 -

在上面的代码中,我们定义了一个类 _TreeGenerator。该类有一个 __init__() 方法,该方法接受一个参数 root_dir,它表示树结构的根目录。此方法将实例变量 self._root_dir 的值设置为作为参数传入的 root_dir,并将其转换为 pathlib.Path 对象。它还初始化一个空列表 self._tree

该类还有一个名为 build_tree() 的方法,用于生成树结构。此方法首先调用 _tree_head() 方法,该方法将 root_dir 和 os.sep 附加到 self._tree 列表。然后它调用 _tree_body() 方法并将其 root_dir 作为参数传递。此方法负责构建树结构的主体。在调用 _tree_body() 方法之后,build_tree() 方法返回 self._tree 列表。

_tree_head 方法用于构建树结构的头部,并由 build_tree 方法调用。它将 root_dir 和 os.sep 附加到 self._tree 列表中。

以上代码是代码片段的第一部分。现在我们将在 _TreeGenerator 类中创建 _tree_body() 方法。让我们看下面的代码。

示例 -

解释 -

此代码定义了一个类 _TreeGenerator。该类有一个 __init__() 方法,它接受一个参数 root_dir,它表示树结构的根目录。此方法将实例变量 self._root_dir 的值设置为作为参数传入的 root_dir,并将其转换为 pathlib.Path 对象。它还初始化一个空列表 self._tree

该类还有一个名为 build_tree() 的方法,用于生成树结构。此方法首先调用 _tree_head() 方法,该方法将 root_dir 和 os.sep 附加到 self._tree 列表。然后它调用 _tree_body() 方法并将其 root_dir 作为参数传递。此方法负责构建树结构的主体。在调用 _tree_body() 方法之后,build_tree() 方法返回 self._tree 列表。

_tree_head() 方法用于构建树结构的头部,并由 build_tree() 方法调用。它将 root_diros.sep 附加到 self._tree 列表。

现在我们将编写 _TreeGenerator 类中的 _tree_body() 方法,它提供了生成目录树状图的核心功能。它将目录路径作为输入,并递归遍历该目录下的文件系统。然后它创建目录结构的可视化表示并生成相应的目录树状图。

示例 -

_tree_body() 方法中的代码提供了类的底层功能。它将目录路径作为参数,遍历该目录下的文件系统,并生成相应的目录树状图。

  1. directory 变量用于存储当前正在处理的目录。
  2. prefix 变量用于存储目录树的当前缩进级别,用于正确格式化树结构。
  3. entries 变量用于存储当前目录中所有文件和目录的迭代器。
  4. 使用 sorted() 函数,entries 变量被排序,以便目录排在文件之前。
  5. entries_count 变量用于存储当前目录中的总条目数。
  6. 使用 for 循环,脚本遍历目录中的所有条目。对于每个条目,它使用 entry.is_dir() 方法检查该条目是文件还是目录。如果该条目是一个目录,脚本会调用 _add_directory() 方法,传入该条目、其索引、目录中的条目数、当前前缀以及一个连接符,如果它是目录中的最后一个条目,它将是 ELBOW。
  7. 如果它是一个文件,它会调用 _add_file() 方法,传入该条目、当前前缀和连接符。

此方法的目的是遍历目录及其所有子目录,并在遍历过程中将适当的信息添加到树结构中。

运行目录树生成器代码

我们已经在上面部分完成了代码。现在我们将运行代码来生成目录树。在项目的根目录打开 Python 交互式 shell 并输入以下代码。我们也可以创建另一个文件并导入相关类。

示例 -

输出

│
└── sample\
    ├── __pycache__\
    │   └── sample.cpython-38.pyc
    │
    ├── sample.py
    └── __init__.py

输出 - 2:根目录文件

│
├── mytree\
│   ├── hello\
│   │   └── test_hello.py
│   │
│   ├── sample\
│   │   └── sample\
│   │       ├── __pycache__\
│   │       │   └── sample.cpython-38.pyc
│   │       │
│   │       ├── sample.py
│   │       └── __init__.py
│   │
│   │
│   ├── __pycache__\
│   │   ├── my_tree.cpython-38.pyc
│   │   └── __init__.cpython-38.pyc
│   │
│   ├── cli.py
│   ├── my_tree.py
│   └── __init__.py
│
├── readme.md
└── tree.py

解释 -

此代码从名为 "mytree.py" 的模块中导入一个名为 "DirectoryTreeGenerator" 的类。然后它创建该类的一个实例,名为 "tree",并使用参数 "./sample" 对其进行初始化。最后,它在 "tree" 对象上调用 "generate()" 方法,该方法可能根据传递给构造函数的路径生成目录树。

让我们看看目录树生成器的完整代码实现。

代码实现

我们将根据 DirectoryTreeGenerator() 类中传递的路径获得输出。

结论

本教程介绍了如何使用 Python 生成目录树。我们已经定义了一个循序渐进的过程来实现目标。这个项目在大型应用程序中将非常有用,我们可以轻松识别哪个文件位于哪个目录中。