Hướng dẫn how do i make a tree diagram in python? - làm cách nào để tạo một sơ đồ cây trong python?

Tìm hiểu về cây và cách thực hiện chúng.

Rễ

Một cây như một cấu trúc dữ liệu có thể nhanh chóng trở thành một môn toán học phức tạp (kiểm tra wiki), chúng ta được bao quanh bởi những thứ thực và ảo (thực sự dữ liệu) có thể được mô hình hóa và biểu diễn bởi một cây Hiểu ngay cả ở cấp độ cơ bản.

Lô đất có thể vẽ sơ đồ bằng cách sử dụng igraph. Bạn cũng có thể sử dụng nó ngoại tuyến những ngày này. Ví dụ dưới đây được dự định sẽ được chạy trong sổ ghi chép Jupyter

import plotly.plotly as py
import plotly.graph_objs as go

import igraph
from igraph import *
# I do not endorse importing * like this

#Set Up Tree with igraph

nr_vertices = 25
v_label = map(str, range(nr_vertices))
G = Graph.Tree(nr_vertices, 2) # 2 stands for children number
lay = G.layout('rt')

position = {k: lay[k] for k in range(nr_vertices)}
Y = [lay[k][1] for k in range(nr_vertices)]
M = max(Y)

es = EdgeSeq(G) # sequence of edges
E = [e.tuple for e in G.es] # list of edges

L = len(position)
Xn = [position[k][0] for k in range(L)]
Yn = [2*M-position[k][1] for k in range(L)]
Xe = []
Ye = []
for edge in E:
    Xe+=[position[edge[0]][0],position[edge[1]][0], None]
    Ye+=[2*M-position[edge[0]][1],2*M-position[edge[1]][1], None] 

labels = v_label

#Create Plotly Traces

lines = go.Scatter(x=Xe,
                   y=Ye,
                   mode='lines',
                   line=dict(color='rgb(210,210,210)', width=1),
                   hoverinfo='none'
                   )
dots = go.Scatter(x=Xn,
                  y=Yn,
                  mode='markers',
                  name='',
                  marker=dict(symbol='dot',
                                size=18, 
                                color='#6175c1',    #'#DB4551', 
                                line=dict(color='rgb(50,50,50)', width=1)
                                ),
                  text=labels,
                  hoverinfo='text',
                  opacity=0.8
                  )

# Create Text Inside the Circle via Annotations

def make_annotations(pos, text, font_size=10, 
                     font_color='rgb(250,250,250)'):
    L=len(pos)
    if len(text)!=L:
        raise ValueError('The lists pos and text must have the same len')
    annotations = go.Annotations()
    for k in range(L):
        annotations.append(
            go.Annotation(
                text=labels[k], # or replace labels with a different list 
                                # for the text within the circle  
                x=pos[k][0], y=2*M-position[k][1],
                xref='x1', yref='y1',
                font=dict(color=font_color, size=font_size),
                showarrow=False)
        )
    return annotations  

# Add Axis Specifications and Create the Layout

axis = dict(showline=False, # hide axis line, grid, ticklabels and  title
            zeroline=False,
            showgrid=False,
            showticklabels=False,
            )

layout = dict(title= 'Tree with Reingold-Tilford Layout',  
              annotations=make_annotations(position, v_label),
              font=dict(size=12),
              showlegend=False,
              xaxis=go.XAxis(axis),
              yaxis=go.YAxis(axis),          
              margin=dict(l=40, r=40, b=85, t=100),
              hovermode='closest',
              plot_bgcolor='rgb(248,248,248)'          
              )

# Plot

data=go.Data([lines, dots])
fig=dict(data=data, layout=layout)
fig['layout'].update(annotations=make_annotations(position, v_label))
py.iplot(fig, filename='Tree-Reingold-Tilf')
# use py.plot instead of py.iplot if you're not using a Jupyter notebook

Đầu ra

Tạo các ứng dụng với giao diện dòng lệnh (CLI) thân thiện với người dùng là một kỹ năng hữu ích cho nhà phát triển Python. Với kỹ năng này, bạn có thể tạo các công cụ để tự động hóa và tăng tốc các tác vụ trong môi trường làm việc của bạn. Trong hướng dẫn này, bạn sẽ xây dựng một công cụ tạo cây thư mục Python cho dòng lệnh của bạn.

Ứng dụng sẽ lấy đường dẫn thư mục làm đối số tại dòng lệnh và hiển thị sơ đồ cây thư mục trên màn hình của bạn. Nó cũng sẽ cung cấp các tùy chọn khác để điều chỉnh đầu ra.

Trong hướng dẫn này, bạn sẽ học cách:

  • Tạo một ứng dụng CLI với Python từ
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3CLI application with Python’s
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3
  • Đi ngang qua một cấu trúc thư mục bằng cách sử dụng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4traverse a directory structure using
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4
  • Tạo, định dạng và hiển thị sơ đồ cây thư mụcdirectory tree diagram
  • Lưu sơ đồ cây thư mục vào tệp đầu raoutput file

Bạn có thể tải xuống mã và các tài nguyên khác cần thiết để xây dựng dự án Trình tạo cây thư mục này bằng cách nhấp vào liên kết bên dưới:

Bản demo: Một công cụ máy phát cây thư mục trong Python

Trong hướng dẫn này, bạn sẽ xây dựng một công cụ dòng lệnh để liệt kê nội dung của thư mục hoặc thư mục trong sơ đồ treelike. Đã có một số giải pháp trưởng thành ngoài kia thực hiện nhiệm vụ này. Bạn sẽ tìm thấy các công cụ như lệnh

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5, có sẵn trên hầu hết các hệ điều hành, cộng với các công cụ khác, như Treelib, Dirtriex, v.v. Tuy nhiên, việc tìm ra giải pháp của riêng bạn cho vấn đề này sẽ là một bài tập học tập tốt.

Hướng dẫn này đề cập đến loại công cụ được mô tả ở trên như một trình tạo cây thư mục. Công cụ bạn sẽ xây dựng ở đây sẽ cho phép bạn tạo và hiển thị sơ đồ Treelike liệt kê cấu trúc bên trong của một thư mục nhất định trong hệ thống tệp của bạn. Bạn cũng sẽ tìm thấy sơ đồ này được gọi là sơ đồ cây thư mục trong suốt hướng dẫn.directory tree generator. The tool you’ll build here will allow you to generate and display a treelike diagram listing the internal structure of a given directory in your file system. You’ll also find this diagram referred to as a directory tree diagram throughout the tutorial.

Trình tạo cây thư mục của bạn sẽ có CLI thân thiện với người dùng. Nó cũng cung cấp một số tính năng thú vị, chẳng hạn như hiển thị sơ đồ cây với nội dung của thư mục trên cửa sổ thiết bị đầu cuối của bạn và lưu sơ đồ vào một tệp bên ngoài.

Tại đây, cách ứng dụng sẽ trông như thế nào và hoạt động khi bạn đi đến cuối hướng dẫn này:

Hướng dẫn how do i make a tree diagram in python? - làm cách nào để tạo một sơ đồ cây trong python?

Trình tạo cây thư mục của bạn sẽ cung cấp CLI đầy đủ nhưng tối thiểu với một vài tùy chọn cho phép bạn tạo và hiển thị sơ đồ cây liệt kê tất cả các tệp và thư mục trong một thư mục gốc nhất định.

Tổng quan dự án

Dự án mà bạn sẽ xây dựng trong hướng dẫn này bao gồm một ứng dụng dòng lệnh lấy đường dẫn thư mục làm đối số, đi qua cấu trúc bên trong của nó và tạo sơ đồ treelike liệt kê nội dung của thư mục trong tay. Trong phần này, bạn sẽ có một cái nhìn đầu tiên về vấn đề và một giải pháp khả thi. Bạn cũng sẽ quyết định làm thế nào để đưa ra dự án.

Đặt dự án

Để xây dựng trình tạo cây thư mục của bạn, bạn sẽ tạo một vài mô -đun và gói. Sau đó, bạn sẽ cung cấp cho dự án một bố cục ứng dụng Python mạch lạc. Vào cuối hướng dẫn này, thư mục gốc dự án của bạn sẽ có cấu trúc thư mục sau:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py

Thư mục

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
6 là thư mục gốc của dự án. Ở đó, bạn sẽ đặt các tệp sau:

  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    7 cung cấp mô tả và hướng dẫn dự án về cài đặt và chạy ứng dụng. Thêm một tệp readme mô tả và chi tiết vào các dự án của bạn được coi là một thông lệ tốt nhất trong lập trình, đặc biệt nếu bạn có kế hoạch phát hành dự án dưới dạng giải pháp nguồn mở. provides the project description and instructions on installing and running the application. Adding a descriptive and detailed README file to your projects is considered a best practice in programming, especially if you’re planning to release the project as an open source solution.

  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    8 cung cấp một tập lệnh điểm nhập cảnh để bạn chạy ứng dụng. provides an entry-point script for you to run the application.

Sau đó, bạn có thư mục

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
9 chứa gói Python với ba mô -đun:

  1. # __init__.py
    
    """Top-level package for RP Tree."""
    
    __version__ = "0.1.0"
    
    0 cung cấp các chức năng chính của ứng dụng.
    provides the application’s main functionalities.
  2. # __init__.py
    
    """Top-level package for RP Tree."""
    
    __version__ = "0.1.0"
    
    1 cho phép
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    9 dưới dạng gói Python.
    enables
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    9 as a Python package.
  3. # __init__.py
    
    """Top-level package for RP Tree."""
    
    __version__ = "0.1.0"
    
    3 cung cấp giao diện dòng lệnh cho ứng dụng.
    provides the command-line interface for the application.

Công cụ Trình tạo cây thư mục của bạn sẽ chạy trên dòng lệnh. Nó sẽ lấy các đối số, xử lý chúng và hiển thị sơ đồ cây thư mục trên cửa sổ thiết bị đầu cuối. Nó cũng có thể lưu sơ đồ đầu ra vào một tệp ở định dạng đánh dấu.

Phác thảo các giải pháp

Đi qua một thư mục trong hệ thống tệp của bạn và tạo sơ đồ cây thân thiện với người dùng phản ánh nội dung của nó có thể không giống như một nhiệm vụ khó khăn ngay từ cái nhìn đầu tiên. Tuy nhiên, khi bạn bắt đầu nghĩ về nó, bạn nhận ra rằng nó che giấu rất nhiều sự phức tạp.

Trước hết, đó là một vấn đề liên quan đến đệ quy. Giả sử bạn có trình quản lý tệp của bạn mở tại thư mục nhà của bạn và bạn đang tìm kiếm một tệp cụ thể. Sau đó, bạn bấm đúp vào thư mục con

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
4 và hiển thị nội dung của nó trên màn hình của bạn. Nếu tập tin ở đó, thì bạn mở nó. Nếu không, bạn mở một thư mục con khác và tiếp tục tìm kiếm. Bạn có thể mô tả quá trình này với các bước sau:

  1. Mở một thư mục.
  2. Kiểm tra nội dung thư mục.
  3. Nếu tập tin được tìm thấy, hãy mở nó. Nếu không, hãy quay lại bước một.

Kết luận là làm việc với các thư mục và nội dung của chúng là một vấn đề mà bạn sẽ thường xuyên tiếp cận bằng cách sử dụng đệ quy. Đó là con đường mà bạn sẽ đi theo trong hướng dẫn này. Nói chung, bạn sẽ chạy các bước sau:

  1. Nhận đường dẫn đến một thư mục trên hệ thống tệp của bạn.
  2. Mở thư mục.
  3. Nhận một danh sách tất cả các mục của nó (thư mục và tập tin).
  4. Nếu thư mục chứa các thư mục con, thì hãy lặp lại quy trình từ bước hai.

Để chạy bước đầu tiên, bạn cần cung cấp một cách để ứng dụng của mình đi theo đường dẫn thư mục tại dòng lệnh. Để làm điều này, bạn sẽ sử dụng mô -đun Python từ ____23 từ thư viện tiêu chuẩn.

Để hoàn thành các bước thứ hai và thứ ba, bạn sẽ sử dụng

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
4. Mô -đun này cung cấp một số công cụ để quản lý và đại diện cho các đường dẫn hệ thống tệp. Cuối cùng, bạn sẽ sử dụng danh sách Python thông thường để lưu trữ danh sách các mục trong cấu trúc thư mục.

Điểm thứ hai cần xem xét là làm thế nào để định hình một sơ đồ cây đẹp mắt phản ánh cấu trúc thư mục theo cách chính xác và thân thiện với người dùng. Trong hướng dẫn này, bạn sẽ định hình các sơ đồ cây của mình bằng cách sử dụng một chiến lược bắt chước những gì lệnh

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5 làm, vì vậy các sơ đồ của bạn sẽ trông giống như cái bạn đã thấy trong phần trên.

Tổ chức mã

Về thiết kế, nếu bạn nghĩ về vấn đề trong tay và áp dụng nguyên tắc tự chịu trách nhiệm, thì bạn có thể sắp xếp mã của ứng dụng Trình tạo cây thư mục theo ba trách nhiệm chính:

  1. Cung cấp CLI
  2. Đi bộ thư mục gốc và xây dựng sơ đồ cây
  3. Hiển thị sơ đồ cây

Mã liên quan đến CLI sẽ sống trong

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3. Trong
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0, bạn sẽ đặt mã liên quan đến trách nhiệm thứ hai và thứ ba.

Trong ví dụ này, bạn sẽ viết một lớp

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 cấp cao để tạo và hiển thị sơ đồ cây. Bạn sẽ sử dụng lớp này trong mã máy khách hoặc chức năng chính. Lớp sẽ cung cấp một phương thức gọi là
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1 để tạo và hiển thị sơ đồ cây thư mục.

Tiếp theo, bạn sẽ mã hóa một lớp

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 cấp thấp để đi bộ cấu trúc thư mục và tạo danh sách chứa các mục định hình sơ đồ cây. Lớp này sẽ cung cấp một phương thức gọi là
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
3 để thực hiện thao tác này.

Sơ đồ cây sẽ có hai thành phần chính:

  1. Đầu sẽ cung cấp biểu diễn thư mục gốc. will provide the root directory representation.
  2. Cơ thể sẽ cung cấp biểu diễn nội dung thư mục. will provide the directory content representation.

Biểu diễn đầu cây sẽ bao gồm tên của thư mục gốc và ký tự ống bổ sung (

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
4) để kết nối đầu và thân cây.

Biểu diễn thân cây sẽ bao gồm các chuỗi bao gồm các thành phần sau:

  • Một chuỗi tiền tố cung cấp khoảng cách cần thiết để phản ánh vị trí của một mục trong cấu trúc thư mục
  • Một ký tự kết nối thư mục con hoặc tệp hiện tại với thư mục chính của nó
  • Tên của thư mục con hoặc tệp hiện tại

Ở đây, cách thức bạn kết hợp các yếu tố này để xây dựng sơ đồ cây thư mục:

Hướng dẫn how do i make a tree diagram in python? - làm cách nào để tạo một sơ đồ cây trong python?

Phương pháp Trình tạo cây của bạn

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
3 sẽ trả về một danh sách với tất cả các mục định hình sơ đồ cây thư mục. Để hiển thị sơ đồ, bạn cần gọi
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1 trên đối tượng cây thư mục của bạn.

Điều kiện tiên quyết

Để hoàn thành hướng dẫn này và tận dụng tối đa nó, bạn nên thoải mái với các khái niệm sau:

  • Tạo giao diện dòng lệnh (CLI) với mô-đun Python từ
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3
    with Python’s
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3 module
  • Đi qua hệ thống tệp với
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4
    with
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4
  • Sử dụng đệ quy và tạo các chức năng đệ quy trong Python and creating recursive functions in Python
  • Làm việc với các tệp bằng cách sử dụng câu lệnh
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    9 và
    # rptree.py
    
    """This module provides RP Tree main module."""
    
    import os
    import pathlib
    
    PIPE = "│"
    ELBOW = "└──"
    TEE = "├──"
    PIPE_PREFIX = "│   "
    SPACE_PREFIX = "    "
    
    0
    using
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    9 and the
    # rptree.py
    
    """This module provides RP Tree main module."""
    
    import os
    import pathlib
    
    PIPE = "│"
    ELBOW = "└──"
    TEE = "├──"
    PIPE_PREFIX = "│   "
    SPACE_PREFIX = "    "
    
    0 statement
  • Sử dụng
    # rptree.py
    
    """This module provides RP Tree main module."""
    
    import os
    import pathlib
    
    PIPE = "│"
    ELBOW = "└──"
    TEE = "├──"
    PIPE_PREFIX = "│   "
    SPACE_PREFIX = "    "
    
    1 để in văn bản lên màn hình và cũng để ghi vào các tệp vật lý trong hệ thống tệp của bạn
    to print text to the screen and also to write to physical files in your file system
  • Sử dụng lập trình hướng đối tượng trong Python in Python

Nếu bạn không có tất cả các kiến ​​thức cần thiết trước khi bắt đầu hướng dẫn này, thì điều đó không sao! Bạn luôn có thể dừng lại và xem xét các tài nguyên sau:

  • Cách xây dựng các giao diện dòng lệnh trong Python với Argparse
  • Mô -đun Python 3 Pathlib: Taming hệ thống tệp
  • Suy nghĩ đệ quy trong Python
  • Làm việc với các tệp trong Python
  • Hướng dẫn của bạn về hàm python in ()
  • Lập trình hướng đối tượng (OOP) trong Python 3

Về mặt phụ thuộc phần mềm, dự án Trình tạo cây thư mục của bạn không cần bất kỳ thư viện bên ngoài nào. Tất cả các phụ thuộc của nó có sẵn dưới dạng các hàm tích hợp Python hoặc là các mô-đun trong thư viện tiêu chuẩn.

Điều đó nói rằng, đó là thời gian để có được bàn tay của bạn với mã thực và xây dựng công cụ tạo cây thư mục của riêng bạn!

Bước 1: Thiết lập cấu trúc dự án

Đầu tiên, bạn cần tạo bố cục ứng dụng mạch lạc cho dự án Trình tạo cây thư mục của mình. Hãy tiếp tục và tạo một thư mục mới trên hệ thống tệp của bạn với tên

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
6. Bên trong thư mục này, bạn cần hai tệp trống:

  1. ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    7
  2. ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    8

Tiếp theo, bạn cần tạo một thư mục con được gọi là

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
9 với các tệp trống sau trong đó:
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0,
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
1 và -
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3. Với bổ sung này, thư mục gốc của dự án của bạn sẽ trông như thế này:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py

Để tải xuống các tệp này và mã bạn sẽ thêm vào chúng trong phần này, nhấp vào liên kết bên dưới:

Tại thời điểm này, bạn cần một bước thiết lập bổ sung. Bắn lên trình chỉnh sửa mã yêu thích của bạn hoặc IDE vào thư mục dự án của bạn, mở

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
1 và thêm nội dung sau:

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"

Python sử dụng các tệp

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
1 để biến thư mục bình thường thành một gói. Các gói chứa các mô -đun, chẳng hạn như
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0 và
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3 trong dự án này. Các gói và mô -đun là các cơ chế cho phép bạn sắp xếp và cấu trúc mã Python của bạn.

Trong trường hợp này,

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
1 chứa chuỗi tài liệu mô -đun, thường được gọi là DocString. Nó cũng xác định một hằng số toàn cầu được gọi là
# rptree.py
# Snip...

class DirectoryTree:
    def __init__(self, root_dir):
        self._generator = _TreeGenerator(root_dir)

    def generate(self):
        tree = self._generator.build_tree()
        for entry in tree:
            print(entry)
4, giữ số phiên bản ứng dụng.docstring. It also defines a global constant called
# rptree.py
# Snip...

class DirectoryTree:
    def __init__(self, root_dir):
        self._generator = _TreeGenerator(root_dir)

    def generate(self):
        tree = self._generator.build_tree()
        for entry in tree:
            print(entry)
4, which holds the application’s version number.

Cuối cùng, bạn cần một thư mục mẫu để kiểm tra ứng dụng và đảm bảo nó hoạt động chính xác. Để lại thư mục gốc dự án của bạn và tạo cấu trúc thư mục sau trong hệ thống tệp của bạn, bên cạnh thư mục dự án của bạn:

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE

Cấu trúc thư mục này bắt chước bố cục chung của một dự án Python. Bạn sẽ sử dụng cấu trúc thư mục mẫu này để kiểm tra công cụ tạo cây thư mục trong suốt các bước trong hướng dẫn này. Bằng cách này, bạn có thể so sánh kết quả của mình với kết quả dự kiến ​​ở bất kỳ bước nào trên hướng dẫn.

Bước 2: Tạo sơ đồ cây thư mục trong Python

Bây giờ bạn đã biết các yêu cầu của dự án và bạn đã thiết lập bố cục dự án và thư mục mẫu, bạn có thể bắt đầu làm việc trên mã thực. Vì vậy, hãy để biên tập viên của bạn sẵn sàng để nhảy vào mã hóa.

Trong phần này, bạn sẽ mã hóa chức năng chính của dự án. Nói cách khác, bạn sẽ viết mã để tạo sơ đồ cây thư mục đầy đủ từ đường dẫn thư mục đầu vào. Để tải xuống mã đó, nhấp vào liên kết bên dưới:

Bây giờ hãy quay lại với Trình chỉnh sửa mã của bạn và mở

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0. Sau đó thêm mã sau vào tệp:

# rptree.py

"""This module provides RP Tree main module."""

import os
import pathlib

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "

Trong đoạn mã này, trước tiên bạn nhập

# rptree.py
# Snip...

class DirectoryTree:
    def __init__(self, root_dir):
        self._generator = _TreeGenerator(root_dir)

    def generate(self):
        tree = self._generator.build_tree()
        for entry in tree:
            print(entry)
6 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
4 từ thư viện tiêu chuẩn Python. Tiếp theo, bạn xác định một số hằng số cấp độ mô-đun để giữ các ký tự đầu nối và chuỗi tiền tố mà bạn sẽ sử dụng để vẽ sơ đồ cây trên cửa sổ thiết bị đầu cuối. Các biểu tượng mà bạn sẽ sử dụng để vẽ sơ đồ cây là cùng một biểu tượng mà bạn đã thấy trong các sơ đồ trước trong hướng dẫn này. Công cụ dòng lệnh
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5 sử dụng các ký hiệu tương tự này để vẽ sơ đồ cây.

Mã hóa lớp ../hello/ │ ├── hello/ │ ├── __init__.py │ └── hello.py │ ├── tests/ │ └── test_hello.py │ ├── requirements.txt ├── setup.py ├── README.md └── LICENSE 0 cấp cao

Tiếp theo, bạn sẽ xác định một lớp cấp cao để tạo sơ đồ cây thư mục và hiển thị nó trên màn hình của bạn. Đặt tên cho lớp

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 và thêm mã sau vào nó:

# rptree.py
# Snip...

class DirectoryTree:
    def __init__(self, root_dir):
        self._generator = _TreeGenerator(root_dir)

    def generate(self):
        tree = self._generator.build_tree()
        for entry in tree:
            print(entry)

Trong trình khởi tạo lớp, bạn lấy một thư mục gốc làm đối số và tạo một thuộc tính thể hiện được gọi là

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    def __init__(self, root_dir):
 6        self._root_dir = pathlib.Path(root_dir)
 7        self._tree = []
 8
 9    def build_tree(self):
10        self._tree_head()
11        self._tree_body(self._root_dir)
12        return self._tree
13
14    def _tree_head(self):
15        self._tree.append(f"{self._root_dir}{os.sep}")
16        self._tree.append(PIPE)
1. Để tạo thuộc tính này, bạn sử dụng một kỹ thuật OOP có tên thành phần xác định một mối quan hệ có một mối quan hệ. Điều này có nghĩa là mỗi đối tượng
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 có một đối tượng
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 được đính kèm.“has a” relationship. This means that every
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 object has a
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 object attached.

Bạn sẽ thấy cách tạo lớp

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 này trong một phút. Bây giờ, hãy xem
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1. Phương pháp này tạo ra một biến cục bộ gọi là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5 giữ kết quả của việc gọi
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
3 trên đối tượng Trình tạo cây. Sau đó, bạn sử dụng vòng lặp
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    def __init__(self, root_dir):
 6        self._root_dir = pathlib.Path(root_dir)
 7        self._tree = []
 8
 9    def build_tree(self):
10        self._tree_head()
11        self._tree_body(self._root_dir)
12        return self._tree
13
14    def _tree_head(self):
15        self._tree.append(f"{self._root_dir}{os.sep}")
16        self._tree.append(PIPE)
8 để in mỗi
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    def __init__(self, root_dir):
 6        self._root_dir = pathlib.Path(root_dir)
 7        self._tree = []
 8
 9    def build_tree(self):
10        self._tree_head()
11        self._tree_body(self._root_dir)
12        return self._tree
13
14    def _tree_head(self):
15        self._tree.append(f"{self._root_dir}{os.sep}")
16        self._tree.append(PIPE)
9 trên cây lên màn hình của bạn.

Mã hóa lớp ../hello/ │ ├── hello/ │ ├── __init__.py │ └── hello.py │ ├── tests/ │ └── test_hello.py │ ├── requirements.txt ├── setup.py ├── README.md └── LICENSE 2 cấp thấp

Bây giờ bạn đã hoàn thành mã hóa

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0, đã đến lúc mã hóa lớp đi qua hệ thống tệp và tạo sơ đồ cây thư mục:

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    def __init__(self, root_dir):
 6        self._root_dir = pathlib.Path(root_dir)
 7        self._tree = []
 8
 9    def build_tree(self):
10        self._tree_head()
11        self._tree_body(self._root_dir)
12        return self._tree
13
14    def _tree_head(self):
15        self._tree.append(f"{self._root_dir}{os.sep}")
16        self._tree.append(PIPE)

Ở đây, cách thức hoạt động của mã này:

  • Dòng 4 xác định một lớp mới,

    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    2. defines a new class,
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    2.

  • Dòng 5 xác định trình khởi tạo lớp. Trong trường hợp này,

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    3 lấy
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 làm đối số. Nó giữ đường dẫn thư mục gốc cây. Lưu ý rằng bạn biến
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 thành đối tượng
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    6 và gán nó cho thuộc tính thể hiện không công khai
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    7.
    defines the class initializer. In this case,
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    3 takes
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 as an argument. It holds the tree’s root directory path. Note that you turn
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 into a
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    6 object and assign it to the nonpublic instance attribute
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    7.

  • Dòng 7 xác định một danh sách trống để lưu trữ các mục định hình sơ đồ cây thư mục. defines an empty list to store the entries that shape the directory tree diagram.

  • Dòng 9 đến 12 Xác định

    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    3. Phương pháp công khai này tạo ra và trả về sơ đồ cây thư mục. Bên trong
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    3, trước tiên bạn gọi
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    0 để xây dựng đầu cây. Sau đó, bạn gọi
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1 với
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    7 như một đối số để tạo phần còn lại của sơ đồ.
    define
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    3. This public method generates and returns the directory tree diagram. Inside
    ../hello/
    │
    ├── hello/
    │   ├── __init__.py
    │   └── hello.py
    │
    ├── tests/
    │   └── test_hello.py
    │
    ├── requirements.txt
    ├── setup.py
    ├── README.md
    └── LICENSE
    
    3, you first call
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    0 to build the tree head. Then you call
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1 with
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    7 as an argument to generate the rest of the diagram.

  • Dòng 14 đến 16 Xác định

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    0. Phương pháp này thêm tên của thư mục gốc vào
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4. Sau đó, bạn thêm
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    5 để kết nối thư mục gốc với phần còn lại của cây.
    define
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    0. This method adds the name of the root directory to
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4. Then you add a
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    5 to connect the root directory to the rest of the tree.

Cho đến thời điểm này, bạn đã mã hóa chỉ là phần đầu tiên của lớp. Bước tiếp theo là viết

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
1, sẽ lấy một số dòng mã.

Mã trong

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
1 cung cấp chức năng cấp thấp của lớp. Nó lấy một đường dẫn thư mục làm đối số, đi qua hệ thống tệp trong thư mục đó và tạo sơ đồ cây thư mục tương ứng. Ở đây, việc thực hiện nó:

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _tree_body(self, directory, prefix=""):
 8        entries = directory.iterdir()
 9        entries = sorted(entries, key=lambda entry: entry.is_file())
10        entries_count = len(entries)
11        for index, entry in enumerate(entries):
12            connector = ELBOW if index == entries_count - 1 else TEE
13            if entry.is_dir():
14                self._add_directory(
15                    entry, index, entries_count, prefix, connector
16                )
17            else:
18                self._add_file(entry, prefix, connector)

Rất nhiều điều đang xảy ra trong mã này. Ở đây, những gì nó làm, từng dòng:

  • Dòng 7 xác định

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1. Phương pháp này có hai đối số: defines
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1. This method takes two arguments:

    1.  1# rptree.py
       2# Snip...
       3
       4class _TreeGenerator:
       5    # Snip...
       6
       7    def _add_directory(
       8        self, directory, index, entries_count, prefix, connector
       9    ):
      10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
      11        if index != entries_count - 1:
      12            prefix += PIPE_PREFIX
      13        else:
      14            prefix += SPACE_PREFIX
      15        self._tree_body(
      16            directory=directory,
      17            prefix=prefix,
      18        )
      19        self._tree.append(prefix.rstrip())
      20
      21    def _add_file(self, file, prefix, connector):
      22        self._tree.append(f"{prefix}{connector} {file.name}")
      
      9 giữ đường dẫn đến thư mục bạn muốn đi qua. Lưu ý rằng
       1# rptree.py
       2# Snip...
       3
       4class _TreeGenerator:
       5    # Snip...
       6
       7    def _add_directory(
       8        self, directory, index, entries_count, prefix, connector
       9    ):
      10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
      11        if index != entries_count - 1:
      12            prefix += PIPE_PREFIX
      13        else:
      14            prefix += SPACE_PREFIX
      15        self._tree_body(
      16            directory=directory,
      17            prefix=prefix,
      18        )
      19        self._tree.append(prefix.rstrip())
      20
      21    def _add_file(self, file, prefix, connector):
      22        self._tree.append(f"{prefix}{connector} {file.name}")
      
      9 phải là đối tượng
       1# rptree.py
       2# Snip...
       3
       4class _TreeGenerator:
       5    # Snip...
       6
       7    def _tree_body(self, directory, prefix=""):
       8        entries = directory.iterdir()
       9        entries = sorted(entries, key=lambda entry: entry.is_file())
      10        entries_count = len(entries)
      11        for index, entry in enumerate(entries):
      12            connector = ELBOW if index == entries_count - 1 else TEE
      13            if entry.is_dir():
      14                self._add_directory(
      15                    entry, index, entries_count, prefix, connector
      16                )
      17            else:
      18                self._add_file(entry, prefix, connector)
      
      6.
      holds the path to the directory you want to walk through. Note that
       1# rptree.py
       2# Snip...
       3
       4class _TreeGenerator:
       5    # Snip...
       6
       7    def _add_directory(
       8        self, directory, index, entries_count, prefix, connector
       9    ):
      10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
      11        if index != entries_count - 1:
      12            prefix += PIPE_PREFIX
      13        else:
      14            prefix += SPACE_PREFIX
      15        self._tree_body(
      16            directory=directory,
      17            prefix=prefix,
      18        )
      19        self._tree.append(prefix.rstrip())
      20
      21    def _add_file(self, file, prefix, connector):
      22        self._tree.append(f"{prefix}{connector} {file.name}")
      
      9 should be a
       1# rptree.py
       2# Snip...
       3
       4class _TreeGenerator:
       5    # Snip...
       6
       7    def _tree_body(self, directory, prefix=""):
       8        entries = directory.iterdir()
       9        entries = sorted(entries, key=lambda entry: entry.is_file())
      10        entries_count = len(entries)
      11        for index, entry in enumerate(entries):
      12            connector = ELBOW if index == entries_count - 1 else TEE
      13            if entry.is_dir():
      14                self._add_directory(
      15                    entry, index, entries_count, prefix, connector
      16                )
      17            else:
      18                self._add_file(entry, prefix, connector)
      
      6 object.

    2. ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      02 giữ một chuỗi tiền tố mà bạn sử dụng để vẽ sơ đồ cây trên cửa sổ thiết bị đầu cuối. Chuỗi này giúp hiển thị vị trí của thư mục hoặc tệp trong hệ thống tệp. holds a prefix string that you use to draw the tree diagram on the terminal window. This string helps to show up the position of the directory or file in the file system.

  • Dòng 8 gọi

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    03 trên
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 và gán kết quả cho
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    05. Cuộc gọi này đến
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    03 trả về một trình lặp lại trên các tệp và thư mục con có trong
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9.
    calls
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    03 on
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 and assign the result to
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    05. This call to
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    03 returns an iterator over the files and subdirectories contained in
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9.

  • Dòng 9 sắp xếp các mục trong

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 bằng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    09. Để thực hiện điều này, bạn tạo chức năng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    10 kiểm tra xem
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    def __init__(self, root_dir):
     6        self._root_dir = pathlib.Path(root_dir)
     7        self._tree = []
     8
     9    def build_tree(self):
    10        self._tree_head()
    11        self._tree_body(self._root_dir)
    12        return self._tree
    13
    14    def _tree_head(self):
    15        self._tree.append(f"{self._root_dir}{os.sep}")
    16        self._tree.append(PIPE)
    
    9 có phải là một tệp và trả về
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    12 hoặc
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    13 phù hợp. Trong Python,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    12 và
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    13 được thể hiện bên trong dưới dạng số nguyên, lần lượt là
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    16 và
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    17. Hiệu ứng ròng là
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    09 đặt các thư mục trước vì
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    19 và các tệp sau chúng vì
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    20.
    sorts the entries in
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 using
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    09. To do this, you create a
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    10 function that checks if
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    def __init__(self, root_dir):
     6        self._root_dir = pathlib.Path(root_dir)
     7        self._tree = []
     8
     9    def build_tree(self):
    10        self._tree_head()
    11        self._tree_body(self._root_dir)
    12        return self._tree
    13
    14    def _tree_head(self):
    15        self._tree.append(f"{self._root_dir}{os.sep}")
    16        self._tree.append(PIPE)
    
    9 is a file and returns
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    12 or
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    13 accordingly. In Python,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    12 and
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    13 are internally represented as integer numbers,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    16 and
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    17, respectively. The net effect is that
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    09 places the directories first because
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    19 and the files after them because
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    20.

  • Dòng 10 gọi

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    21 để có được số lượng mục trong
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 trong tay.
    calls
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    21 to get the number of entries in the
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9 at hand.

  • Các dòng 11 bắt đầu một vòng

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    def __init__(self, root_dir):
     6        self._root_dir = pathlib.Path(root_dir)
     7        self._tree = []
     8
     9    def build_tree(self):
    10        self._tree_head()
    11        self._tree_body(self._root_dir)
    12        return self._tree
    13
    14    def _tree_head(self):
    15        self._tree.append(f"{self._root_dir}{os.sep}")
    16        self._tree.append(PIPE)
    
    8 lặp lại trên các mục trong
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9. Vòng lặp sử dụng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    25 để liên kết một chỉ mục với mỗi mục.
    starts a
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    def __init__(self, root_dir):
     6        self._root_dir = pathlib.Path(root_dir)
     7        self._tree = []
     8
     9    def build_tree(self):
    10        self._tree_head()
    11        self._tree_body(self._root_dir)
    12        return self._tree
    13
    14    def _tree_head(self):
    15        self._tree.append(f"{self._root_dir}{os.sep}")
    16        self._tree.append(PIPE)
    
    8 loop that iterates over the entries in
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    9. The loop uses
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    25 to associate an index to each entry.

  • Dòng 12 xác định ký hiệu đầu nối mà bạn sẽ sử dụng để vẽ sơ đồ cây trên cửa sổ thiết bị đầu cuối. Ví dụ: nếu mục nhập hiện tại là lần cuối cùng trong thư mục (

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    26), thì bạn sử dụng khuỷu tay (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    27) dưới dạng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    28. Nếu không, bạn sử dụng TEE (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    29).
    defines the connector symbol you’ll use to draw the tree diagram on the terminal window. For example, if the current entry is the last in the directory (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    26), then you use an elbow (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    27) as a
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    28. Otherwise, you use a tee (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    29).

  • Các dòng 13 đến 18 Xác định một câu lệnh có điều kiện kiểm tra xem mục nhập hiện tại có phải là một thư mục không. Nếu vậy, thì khối mã

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    30 gọi
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    31 để thêm một mục thư mục mới. Mặt khác, mệnh đề
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    32 gọi
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    33 để thêm một mục nhập tệp mới.
    define a conditional statement that checks if the current entry is a directory. If so, then the
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    30 code block calls
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    31 to add a new directory entry. Otherwise, the
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    32 clause calls
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    33 to add a new file entry.

Để hoàn thành mã hóa

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2, bạn cần viết
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
31 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
33. Ở đây, mã cho các phương pháp không công khai đó:

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")

Ở đây, những gì mã này làm, từng dòng:

  • Dòng 7 xác định

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    31. Nó có một phương pháp trợ giúp có năm đối số, mà không tính
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    38. Bạn đã biết những gì mỗi đối số này đại diện, vì vậy, không cần phải bao gồm chúng một lần nữa.
    defines
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    31. It’s a helper method that takes five arguments, without counting
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    38. You already know what each of these arguments represents, so there’s no need to cover them again.

  • Dòng 10 nối một thư mục mới vào

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4. Mỗi thư mục trong
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4 được biểu thị bằng một chuỗi chứa
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    28, tên của thư mục (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    43) và một dấu phân cách cuối cùng (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    44). Lưu ý rằng bộ phân cách phụ thuộc vào nền tảng, có nghĩa là trình tạo cây của bạn sử dụng thiết bị tách tương ứng với hệ điều hành hiện tại của bạn.
    appends a new directory to
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4. Each directory in
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    4 is represented by a string containing a
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02, a
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    28, the name of the directory (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    43), and a final separator (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    44). Note that the separator is platform dependent, which means that your tree generator uses the separator that corresponds to your current operating system.

  • Các dòng 11 đến 14 chạy một câu lệnh có điều kiện cập nhật

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02 theo
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    46 của mục nhập hiện tại.
    run a conditional statement that updates
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02 according to the
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    46 of the current entry.

  • Dòng 15 đến 18 gọi

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1 với một bộ đối số mới. call
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _add_directory(
     8        self, directory, index, entries_count, prefix, connector
     9    ):
    10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
    11        if index != entries_count - 1:
    12            prefix += PIPE_PREFIX
    13        else:
    14            prefix += SPACE_PREFIX
    15        self._tree_body(
    16            directory=directory,
    17            prefix=prefix,
    18        )
    19        self._tree.append(prefix.rstrip())
    20
    21    def _add_file(self, file, prefix, connector):
    22        self._tree.append(f"{prefix}{connector} {file.name}")
    
    1 with a new set of arguments.

  • Dòng 19 nối thêm một

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02 mới để phân tách nội dung của thư mục hiện tại khỏi nội dung của phần tiếp theo. appends a new
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    02 to separate the content of the current directory from the content of the next one.

Có một chi tiết quan trọng thảo luận trong cuộc gọi đến

 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
1 trên dòng 15. Đây là một cuộc gọi đệ quy gián tiếp. Nói cách khác,
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
1 đang tự gọi mình bằng
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
31 cho đến khi nó đi qua toàn bộ cấu trúc thư mục.indirect recursive call. In other words,
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
1 is calling itself by means of
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
31 until it traverses the whole directory structure.

Cuối cùng, trên các dòng 21 và 22, bạn xác định

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
33. Phương pháp này nối thêm một mục nhập tệp vào danh sách cây thư mục.

Chạy mã tạo cây thư mục

Ồ! Đó là rất nhiều việc! Trình tạo cây thư mục của bạn bây giờ cung cấp chức năng chính của nó. Nó thời gian để thử. Mở phiên tương tác Python trên thư mục gốc của dự án và nhập mã sau:

>>>

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
0

Tại đây, trước tiên bạn nhập

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 từ
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0. Tiếp theo, bạn tạo một đối tượng cây thư mục, chuyển đường dẫn đến thư mục mẫu
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
55 được tạo trước đó. Khi bạn gọi
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1 trên đối tượng cây thư mục, bạn sẽ nhận được sơ đồ cây thư mục đầy đủ được in trên màn hình của bạn.

Mát mẻ! Bạn đã mã hóa chức năng chính của cây thư mục của bạn. Trong phần tiếp theo, bạn sẽ cung cấp cho dự án của mình một giao diện dòng lệnh tốt và thân thiện với người dùng và tập lệnh thực thi.

Bước 3: Xây dựng Trình tạo cây thư mục CLI CLI

Có một số công cụ ngoài kia để tạo các ứng dụng CLI. Một số trong những cái phổ biến hơn là Click,

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
57, Typer, và cả
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
3, có sẵn trong thư viện tiêu chuẩn. Trong dự án Trình tạo cây thư mục của bạn, bạn sẽ sử dụng
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
3 để cung cấp giao diện dòng lệnh. Bằng cách này, bạn sẽ tránh có một sự phụ thuộc bên ngoài.

Python sườn

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
3 cho phép bạn xác định các đối số mà ứng dụng của bạn sẽ thực hiện tại dòng lệnh và để xác thực đầu vào của người dùng. Mô -đun cũng tạo thông báo trợ giúp và sử dụng cho các tập lệnh của bạn.

Để tải xuống các tệp và mã mà bạn sẽ thêm hoặc sửa đổi trong phần này, nhấp vào liên kết bên dưới:

Để triển khai Trình tạo cây thư mục CLI CLI, hãy quay lại thư mục dự án và mở tệp

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3 từ gói
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
62. Sau đó nhập mã sau:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
1

Trong đoạn mã này, trước tiên bạn nhập các mô -đun cần thiết từ thư viện tiêu chuẩn. Sau đó, bạn nhập

# rptree.py
# Snip...

class DirectoryTree:
    def __init__(self, root_dir):
        self._generator = _TreeGenerator(root_dir)

    def generate(self):
        tree = self._generator.build_tree()
        for entry in tree:
            print(entry)
4 và cũng
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 từ gói chứa,
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
62.

Trong

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
66, trước tiên bạn gọi
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
67 và đóng gói các đối số dòng lệnh trong
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
68. Bạn sẽ thấy những gì chức năng này làm trong một phút. Tiếp theo, bạn biến thư mục gốc thành một đối tượng
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _tree_body(self, directory, prefix=""):
 8        entries = directory.iterdir()
 9        entries = sorted(entries, key=lambda entry: entry.is_file())
10        entries_count = len(entries)
11        for index, entry in enumerate(entries):
12            connector = ELBOW if index == entries_count - 1 else TEE
13            if entry.is_dir():
14                self._add_directory(
15                    entry, index, entries_count, prefix, connector
16                )
17            else:
18                self._add_file(entry, prefix, connector)
6. Câu lệnh có điều kiện thực hiện xác nhận nhanh để đảm bảo rằng người dùng cung cấp đường dẫn thư mục hợp lệ và nếu không thì thoát khỏi ứng dụng.

Cuối cùng, bạn tạo một đối tượng

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 bằng cách sử dụng
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _tree_body(self, directory, prefix=""):
 8        entries = directory.iterdir()
 9        entries = sorted(entries, key=lambda entry: entry.is_file())
10        entries_count = len(entries)
11        for index, entry in enumerate(entries):
12            connector = ELBOW if index == entries_count - 1 else TEE
13            if entry.is_dir():
14                self._add_directory(
15                    entry, index, entries_count, prefix, connector
16                )
17            else:
18                self._add_file(entry, prefix, connector)
4 làm đối số và gọi
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1 trên nó để tạo và hiển thị sơ đồ cây thư mục tương ứng trên cửa sổ thiết bị đầu cuối của bạn.

Bây giờ bạn có thể đi sâu vào mã của

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
67. Hàm này cung cấp tất cả các tính năng liên quan đến CLI:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
2

Ở đây, những gì chức năng này làm:

  • Dòng 5 Instantiates

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    74, cung cấp tên lệnh của ứng dụng (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    75),
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    76 ngắn của chương trình và cụm
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    77 để hiển thị sau khi người dùng chạy tùy chọn trợ giúp ứng dụng. Lớp này cung cấp một trình phân tích cú pháp cho tất cả các đối số mà người dùng loại tại dòng lệnh.
    instantiates
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    74, providing the application’s command name (
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    75), a short
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    76 of the program, and an
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    77 phrase to display after the user runs the application’s help option. This class provides a parser for all the arguments the user types at the command line.

  • Dòng 10 đặt thuộc tính của trình phân tích cú pháp

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    78 thành một chuỗi chứa tên ứng dụng cùng với phiên bản hiện tại của nó,
    # rptree.py
    # Snip...
    
    class DirectoryTree:
        def __init__(self, root_dir):
            self._generator = _TreeGenerator(root_dir)
    
        def generate(self):
            tree = self._generator.build_tree()
            for entry in tree:
                print(entry)
    
    4.
    sets the parser’s
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    78 attribute to a string that holds the application’s name along with its current version,
    # rptree.py
    # Snip...
    
    class DirectoryTree:
        def __init__(self, root_dir):
            self._generator = _TreeGenerator(root_dir)
    
        def generate(self):
            tree = self._generator.build_tree()
            for entry in tree:
                print(entry)
    
    4.

  • Dòng 11 thêm đối số tùy chọn đầu tiên vào ứng dụng của bạn CLI. Cờ

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    80 hoặc
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    81 được yêu cầu để cung cấp đối số này, có hành động mặc định là hiển thị chuỗi phiên bản ứng dụng trên cửa sổ Terminal của bạn.
    adds the first optional argument to your application’s CLI. The
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    80 or
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    81 flag is required to provide this argument, which has the default action of displaying the application’s version string on your terminal window.

  • Các dòng 12 đến 18 Thêm một đối số thứ hai vào CLI. Ở đây,

     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 là một đối số vị trí giữ đường dẫn thư mục mà bạn sẽ sử dụng làm điểm bắt đầu để tạo sơ đồ cây thư mục. Trong trường hợp này, có bốn đối số cho
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    83:
    add a second argument to the CLI. Here,
     1# rptree.py
     2# Snip...
     3
     4class _TreeGenerator:
     5    # Snip...
     6
     7    def _tree_body(self, directory, prefix=""):
     8        entries = directory.iterdir()
     9        entries = sorted(entries, key=lambda entry: entry.is_file())
    10        entries_count = len(entries)
    11        for index, entry in enumerate(entries):
    12            connector = ELBOW if index == entries_count - 1 else TEE
    13            if entry.is_dir():
    14                self._add_directory(
    15                    entry, index, entries_count, prefix, connector
    16                )
    17            else:
    18                self._add_file(entry, prefix, connector)
    
    4 is a positional argument that holds the directory path you’ll use as a starting point to generate the directory tree diagram. In this case, there are four arguments to
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    83:

    1. ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      84 giữ tên của đối số trong các thông báo sử dụng.

    2. ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      85 Xác định số lượng giá trị mà chương trình của bạn có thể thực hiện dưới đối số trong tay. Ví dụ: trình tạo cây thư mục của bạn chỉ có thể đi một đường dẫn thư mục tại dòng lệnh, do đó, giá trị phù hợp cho
      ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      85 là
      ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      87.

    3. ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      88 cung cấp một giá trị mặc định cho đối số trong tay. Trong trường hợp này, bạn sử dụng một dấu chấm (
      ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      89) để đặt thư mục hiện tại làm thư mục gốc mặc định.

    4. ./rptree_project/
      │
      ├── rptree/
      │   ├── rptree.py
      │   ├── __init__.py
      │   └── cli.py
      │
      ├── README.md
      └── tree.py
      
      90 cung cấp một thông báo trợ giúp ngắn gọn mô tả những gì đối số làm.

  • Dòng 19 phân tích các đối số được cung cấp bằng cách sử dụng

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    91. Phương thức này trả về một đối tượng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    92 với tất cả các đối số được cung cấp. Bạn có thể truy cập các đối số này bằng cách sử dụng ký hiệu dấu chấm trên đối tượng không gian tên. Lưu ý rằng bạn đã lưu trữ không gian tên này trong
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    68 khi bạn viết
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    66.
    parses the supplied arguments using
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    91. This method returns a
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    92 object with all the supplied arguments. You can access these arguments using the dot notation on the namespace object. Note that you stored this namespace in
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    68 back when you wrote
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    66.

Hành động cuối cùng để hoàn thành bước này trong hành trình của bạn là cung cấp một kịch bản điểm nhập cảnh. Quay lại trình chỉnh sửa mã của bạn và mở

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
8, sau đó thêm mã sau vào nó:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
3

Tệp này ngắn và đơn giản. Trước tiên, bạn nhập

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
66 từ
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3 và sau đó kết thúc cuộc gọi của nó trong điều kiện
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
98 truyền thống để Python gọi
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
66 chỉ khi bạn chạy tệp dưới dạng chương trình thay vì nhập nó dưới dạng mô -đun.

Với tập lệnh này, bạn có thể bắt đầu sử dụng Trình tạo cây thư mục dòng lệnh hoàn toàn mới của mình. Mở cửa sổ dòng lệnh, di chuyển đến thư mục dự án và chạy các lệnh sau:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
4

Đó là nó! Công cụ tạo cây thư mục của bạn hoạt động. Nó tạo và hiển thị sơ đồ cây thân thiện với người dùng trên màn hình. Nó cũng cung cấp phiên bản và thông tin sử dụng. Điều đó khá tuyệt vời cho khoảng một trăm dòng mã! Trong các phần tiếp theo, bạn sẽ thêm một vài tính năng vào ứng dụng.

Bước 4: Thực hiện tùy chọn chỉ dành cho thư mục

Một tính năng thú vị để thêm vào trình tạo cây thư mục của bạn là khả năng tạo và hiển thị các sơ đồ cây chỉ có thư mục. Nói cách khác, một sơ đồ chỉ hiển thị các thư mục. Trong dự án này, bạn sẽ thêm các cờ

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
01 để hoàn thành việc này, nhưng trước đó, bạn cần cập nhật
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 để nó có thể hỗ trợ tính năng mới này.

Bạn có thể tải xuống các tệp và mã mà bạn sẽ thêm hoặc sửa đổi trong phần này bằng cách nhấp vào liên kết bên dưới:

Bây giờ hãy mở mô -đun

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0 và cập nhật mã của nó như thế này:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5

Đầu tiên, bạn thêm

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
04 làm đối số cho trình khởi tạo lớp. Đây là một đối số Boolean cho phép bạn tạo một cây đầy đủ hoặc cây chỉ có thư mục tùy thuộc vào đầu vào của người dùng tại dòng lệnh. Đối số này mặc định là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13 vì việc tạo một cây đầy đủ là trường hợp sử dụng phổ biến nhất.

Trong dòng được tô sáng thứ hai, bạn tạo một thuộc tính thể hiện được gọi là

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
06 để giữ đối số mới được thêm vào.

Trong dòng được tô sáng thứ ba, bạn thay thế hai dòng mã gốc bằng một cuộc gọi đến

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
07. Như tên của nó cho thấy, hàm này chuẩn bị các mục thư mục để tạo một cây đầy đủ hoặc cây chỉ có thư mục.

Trong

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
07, trước tiên bạn nhận được trình tạo
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
05. Tuyên bố
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
30 kiểm tra xem
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
06 là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
12. Nếu vậy, sau đó bạn lọc ra các tệp với sự hiểu biết danh sách và trả về
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13 của các thư mục. Nếu
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
06 là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13, thì bạn sắp xếp các mục, sử dụng lại cùng một mã bạn đã thấy trước đó. Cuối cùng, bạn trả lại danh sách đầy đủ các mục trong
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    # Snip...
 6
 7    def _add_directory(
 8        self, directory, index, entries_count, prefix, connector
 9    ):
10        self._tree.append(f"{prefix}{connector} {directory.name}{os.sep}")
11        if index != entries_count - 1:
12            prefix += PIPE_PREFIX
13        else:
14            prefix += SPACE_PREFIX
15        self._tree_body(
16            directory=directory,
17            prefix=prefix,
18        )
19        self._tree.append(prefix.rstrip())
20
21    def _add_file(self, file, prefix, connector):
22        self._tree.append(f"{prefix}{connector} {file.name}")
9.

Bây giờ bạn cần đảm bảo rằng bạn chuyển đối số mới này cho trường hợp

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2 trở lại trong
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
6

Trong dòng được tô sáng đầu tiên, bạn thêm một đối số mới gọi là

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
04 vào trình khởi tạo lớp. Trong dòng được tô sáng thứ hai, bạn đảm bảo chuyển đối số mới cho hàm tạo của
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
2.

Với những thay đổi này, bạn có thể cập nhật tệp

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3 để ứng dụng có thể thực hiện và xử lý các cờ
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
01 tại dòng lệnh. Đầu tiên, bạn cần cập nhật
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
66:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
7

Trong dòng được tô sáng, bạn chuyển

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
25 cho đối số
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
04 của
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0. Thuộc tính này của không gian tên
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
68 giữ giá trị boolean phụ thuộc vào đầu vào của người dùng. Nếu người dùng cung cấp tùy chọn
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 hoặc
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
01 tại dòng lệnh, thì
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
25 là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
12. Nếu không, nó
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13.

Tiếp theo, đi và thêm các cờ

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
01 vào giao diện dòng lệnh. Để làm điều đó, bạn cần cập nhật
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
67 như thế này:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
8

Đối số

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
37 trong cuộc gọi đến
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
83 giữ giá trị
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
39, điều đó có nghĩa là đối số này tự động lưu trữ
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
12 hoặc
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13 theo đầu vào của người dùng. Trong trường hợp này, nếu người dùng cung cấp cờ
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 hoặc
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
01 tại dòng lệnh, thì đối số sẽ lưu trữ
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
12. Nếu không, nó lưu trữ
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
13.

Với bản cập nhật này, đó là thời gian để chạy và kiểm tra ứng dụng. Quay lại cửa sổ thiết bị đầu cuối của bạn và thực hiện lệnh sau:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
9

Từ thời điểm này, nếu bạn cung cấp cờ

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
00 hoặc
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
47 tại dòng lệnh, thì sơ đồ cây chỉ hiển thị các thư mục con trong thư mục mẫu
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
55 của bạn.

Bước 5: Lưu sơ đồ cây thư mục vào tệp

Trong phần này, bạn sẽ thêm một tính năng cuối cùng vào công cụ tạo cây thư mục của mình. Bạn sẽ cung cấp cho ứng dụng khả năng lưu sơ đồ cây thư mục được tạo vào một tệp bên ngoài. Để làm điều đó, bạn sẽ thêm một đối số mới vào CLI với các cờ

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
49 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
50.

Như thường lệ, để tải xuống mã mà bạn sẽ thêm hoặc sửa đổi trong phần này, nhấp vào liên kết bên dưới:

Bây giờ quay lại

# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
0 và cập nhật
../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0 như thế này:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
0

Bản cập nhật này gần như là một sự tái tạo đầy đủ của

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0. Đầu tiên, bạn thêm một đối số mới vào trình khởi tạo lớp có tên
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
54. Đối số này mặc định là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
55, là đầu ra tiêu chuẩn (màn hình của bạn). Sau đó, bạn lưu trữ đối số mới được thêm vào trong một thuộc tính thể hiện có tên là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
56.

Trong

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
1, trước tiên bạn xây dựng sơ đồ cây thư mục và lưu trữ nó trong
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
5. Câu lệnh có điều kiện kiểm tra xem người dùng đã cung cấp một tệp đầu ra khác với
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
55. Nếu vậy, thì khối mã
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
30 kết thúc sơ đồ cây trong khối mã đánh dấu bằng cách sử dụng backticks (
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
61).

Tiếp theo, bạn mở tệp đầu ra được cung cấp bằng

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
9 để bạn có thể xử lý nó bằng câu lệnh
# rptree.py

"""This module provides RP Tree main module."""

import os
import pathlib

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "
0.

Trong khối

# rptree.py

"""This module provides RP Tree main module."""

import os
import pathlib

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "
0, bạn bắt đầu vòng lặp
 1# rptree.py
 2# Snip...
 3
 4class _TreeGenerator:
 5    def __init__(self, root_dir):
 6        self._root_dir = pathlib.Path(root_dir)
 7        self._tree = []
 8
 9    def build_tree(self):
10        self._tree_head()
11        self._tree_body(self._root_dir)
12        return self._tree
13
14    def _tree_head(self):
15        self._tree.append(f"{self._root_dir}{os.sep}")
16        self._tree.append(PIPE)
8 để in sơ đồ cây thư mục vào tệp đầu ra được cung cấp. Lưu ý rằng
# rptree.py

"""This module provides RP Tree main module."""

import os
import pathlib

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "
1 cũng có thể ghi vào các tệp thông thường trên hệ thống tệp của bạn. Để làm điều này, bạn chỉ cần cung cấp một đối số
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
67 tùy chỉnh. Để đi sâu hơn vào các tính năng của
# rptree.py

"""This module provides RP Tree main module."""

import os
import pathlib

PIPE = "│"
ELBOW = "└──"
TEE = "├──"
PIPE_PREFIX = "│   "
SPACE_PREFIX = "    "
1, hãy xem hướng dẫn của bạn về hàm python in ().

Khi bạn đã hoàn thành với

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0, bạn có thể cập nhật giao diện dòng lệnh để bật tùy chọn tệp đầu ra. Quay trở lại
# __init__.py

"""Top-level package for RP Tree."""

__version__ = "0.1.0"
3 và sửa đổi nó như thế này:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
1

Bước đầu tiên là lấy tệp đầu ra làm đối số trong hàm tạo

../hello/
│
├── hello/
│   ├── __init__.py
│   └── hello.py
│
├── tests/
│   └── test_hello.py
│
├── requirements.txt
├── setup.py
├── README.md
└── LICENSE
0. Tệp đầu ra, nếu có, sẽ được lưu trữ trong
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
72.

Tiếp theo, bạn thêm một đối số mới vào

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
73. Đối số này có hai lá cờ:
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
49 và
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
50. Để cung cấp một tệp đầu ra thay thế, người dùng phải sử dụng một trong các cờ này và cung cấp đường dẫn đến các tệp ở dòng lệnh. Lưu ý rằng tệp đầu ra mặc định là
./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
55. Bằng cách này, nếu người dùng không cung cấp một tệp đầu ra, thì ứng dụng sẽ tự động sử dụng đầu ra tiêu chuẩn, màn hình.

Bạn có thể kiểm tra tùy chọn mới được thêm vào bằng cách chạy lệnh sau trên thiết bị đầu cuối của bạn:

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
2

Lệnh này tạo ra một sơ đồ cây thư mục đầy đủ và lưu nó vào tệp

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
77 trong thư mục hiện tại của bạn. Nếu bạn mở tệp, thì bạn sẽ thấy sơ đồ cây thư mục được lưu ở đó ở định dạng đánh dấu.

Đó là nó! Dự án Trình tạo cây thư mục của bạn đã hoàn tất. Bên cạnh tùy chọn mặc định tạo và hiển thị sơ đồ cây thư mục đầy đủ, ứng dụng cung cấp các tùy chọn sau:

  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    80,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    81 Hiển thị thông tin phiên bản hiện tại và thoát ứng dụng.
  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    80,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    81 hiển thị thông điệp trợ giúp và sử dụng.
  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    00,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    01 Tạo một cây chỉ dành cho thư mục và in nó vào màn hình.
  • ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    49,
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    85 Tạo cây và lưu nó vào một tệp ở định dạng Markdown.

Bây giờ bạn có một công cụ dòng lệnh đầy đủ chức năng tạo ra sơ đồ cây thư mục thân thiện với người dùng. Bạn đã làm rất tốt!

Sự kết luận

Bạn có thể tự động hóa và tăng tốc một số quy trình và tác vụ trong môi trường làm việc của mình bằng cách tạo các công cụ và ứng dụng CLI. Trong Python, bạn có thể nhanh chóng tạo loại công cụ này bằng cách sử dụng

./rptree_project/
│
├── rptree/
│   ├── rptree.py
│   ├── __init__.py
│   └── cli.py
│
├── README.md
└── tree.py
3 hoặc các thư viện bên thứ ba khác. Trong hướng dẫn này, bạn đã viết một dự án đầy đủ để xây dựng một công cụ tạo cây thư mục Python cho dòng lệnh của bạn.directory tree generator tool for your command line.

Ứng dụng lấy một đường dẫn thư mục ở dòng lệnh, tạo sơ đồ cây thư mục và hiển thị nó trên cửa sổ thiết bị đầu cuối của bạn hoặc lưu nó vào một tệp bên ngoài trên hệ thống tệp của bạn. Nó cũng cung cấp thêm một vài tùy chọn để điều chỉnh sơ đồ cây kết quả.

Trong hướng dẫn này, bạn đã học được cách:

  • Tạo một ứng dụng CLI với Python từ
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3CLI application with Python’s
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    3
  • Đi ngang qua một cấu trúc thư mục bằng cách sử dụng
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4traverse a directory structure using
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    4
  • Tạo, định dạng và in sơ đồ cây thư mụcdirectory tree diagram
  • Lưu sơ đồ cây thư mục vào tệp đầu raoutput file

Mã nguồn cuối cùng cho dự án Trình tạo cây thư mục có sẵn để bạn tải xuống. Để có được nó, nhấp vào liên kết bên dưới:

Bước tiếp theo

Cho đến thời điểm này, bạn đã xây dựng một công cụ tạo cây thư mục đầy đủ chức năng. Mặc dù ứng dụng cung cấp một bộ tính năng tối thiểu, nhưng nó là một điểm khởi đầu tốt để bạn tiếp tục thêm các tính năng và học tập trong quá trình. Điều này sẽ giúp bạn đưa các kỹ năng của bạn với các ứng dụng Python và CLI lên cấp độ tiếp theo.

Dưới đây là một vài ý tưởng bạn có thể thực hiện để tiếp tục cải thiện công cụ tạo cây thư mục của mình:

  • Thêm hỗ trợ cho việc sắp xếp các tệp và thư mục: Khả năng sắp xếp các tệp và thư mục là một tính năng tuyệt vời để có. Ví dụ: bạn có thể thêm các cờ Boolean

    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    89 và ____290 để cho phép người dùng điều chỉnh thứ tự các tệp và thư mục trong sơ đồ cây cuối cùng. The ability to sort files and directories is a great feature to have. For example, you can add
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    89 and
    ./rptree_project/
    │
    ├── rptree/
    │   ├── rptree.py
    │   ├── __init__.py
    │   └── cli.py
    │
    ├── README.md
    └── tree.py
    
    90 Boolean flags to allow the user to tweak the order of files and directories in the final tree diagram.

  • Thêm các biểu tượng và màu sắc vào sơ đồ cây: Thêm biểu tượng, màu phông chữ hoặc cả hai cũng là một tính năng tốt để thực hiện. Ví dụ: bạn có thể sử dụng các biểu tượng thư mục tùy chỉnh cho các thư mục và các biểu tượng dựa trên loại tệp cho các tệp. Adding icons, font colors, or both is also a nice feature to implement. For example, you can use custom folder icons for the directories and file type–based icons for the files.

  • Thiết lập ứng dụng để xuất bản nó dưới dạng dự án nguồn mở: Chuẩn bị ứng dụng để xuất bản lên PYPI như một dự án nguồn mở có thể là một thách thức thú vị để bạn thực hiện. Làm như vậy sẽ cho phép bạn chia sẻ công việc của bạn với bạn bè và đồng nghiệp của bạn. Để bắt đầu với các gói xuất bản lên PYPI, hãy xem cách xuất bản gói Python nguồn mở thành PYPI. Preparing the application to publish to PyPI as an open source project might be an interesting challenge for you to take. Doing so will allow you to share your work with your friends and colleagues. To get started with publishing packages to PyPI, check out How to Publish an Open-Source Python Package to PyPI.

Đây chỉ là một vài ý tưởng về cách bạn có thể tiếp tục thêm các tính năng vào trình tạo cây thư mục của mình. Thực hiện thử thách và xây dựng một cái gì đó tuyệt vời trên đỉnh này!

Có một cây được xây dựng trong Python?

Rễ của cây (5) nằm trên đầu. Python không có hỗ trợ tích hợp cho cây.Python does not have built-in support for trees.

Có một lớp cây trong Python?

Python Treende Class A Treenode là một cấu trúc dữ liệu đại diện cho một mục của cây, bao gồm nhiều nút như vậy.Nút trên cùng của một cây được gọi là gốc rễ và mỗi nút (ngoại trừ nút gốc) được liên kết với một nút cha. A TreeNode is a data structure that represents one entry of a tree, which is composed of multiple of such nodes. The topmost node of a tree is called the “root”, and each node (with the exception of the root node) is associated with one parent node.

Làm thế nào để bạn hình dung một cây quyết định trong Python?

Tạo và hình dung cây quyết định với Python..
Dữ liệu: Bộ dữ liệu IRIS.Nhập sklearn.dataSets dưới dạng bộ dữ liệu nhập gấu trúc dưới dạng pd iris = datasets.load_iris () df = pd.dataframe (iris.data, cột = iris.feature_names) y = iris.target.....
Mô hình: Phân loại rừng ngẫu nhiên.....
Tạo ra hình dung ..

Làm thế nào để cây hoạt động trong Python?

Cây là một cấu trúc dữ liệu trong đó các mục dữ liệu được kết nối bằng các tham chiếu theo cách phân cấp.Mỗi cây bao gồm một nút gốc mà từ đó chúng ta có thể truy cập từng phần tử của cây.Bắt đầu từ nút gốc, mỗi nút chứa 0 hoặc nhiều nút được kết nối với nó khi còn nhỏ.data items are connected using references in a hierarchical manner. Each Tree consists of a root node from which we can access each element of the tree. Starting from the root node, each node contains zero or more nodes connected to it as children.