Python實現優雅的目錄結構打印工具
在軟件開發、系統管理和日常工作中,我們經常需要查看和分析目錄結構。
工具功能概述
這個DirectoryPrinter
類提供了以下功能:
- 遞歸打印目錄結構
- 可配置是否顯示隱藏文件
- 可設置最大遞歸深度
- 自定義縮進和文件/文件夾符號
- 友好的交互式配置界面
核心代碼解析
初始化配置
def __init__(self, root_dir, show_hidden=False, depth=0, max_depth=None, indent_symbol='│ ', folder_symbol='/ ', file_symbol='- '):self.root_dir = root_dirself.show_hidden = show_hiddenself.max_depth = max_depthself.indent_symbol = indent_symbolself.folder_symbol = folder_symbolself.file_symbol = file_symbolself.depth = depth
構造函數接收多個參數,允許用戶自定義打印行為。特別是indent_symbol
、folder_symbol
和file_symbol
參數,可以完全改變輸出樣式。
目錄打印邏輯
def print_directory(self):try:items = os.listdir(self.root_dir)except FileNotFoundError:print(f"指定的目錄 {self.root_dir} 不存在")returnexcept PermissionError:print(f"無法訪問目錄 {self.root_dir}")return# 過濾隱藏文件if not self.show_hidden:items = [item for item in items if not (item.startswith('.') and os.path.isfile(os.path.join(self.root_dir, item)))]
方法首先嘗試列出目錄內容,并處理可能出現的異常。然后根據配置過濾隱藏文件。
遞歸打印
for index, item in enumerate(sorted(items), start=1):path = os.path.join(self.root_dir, item)is_dir = os.path.isdir(path)# 構建前綴prefix = self.indent_symbol * self.depthif index == len(items):if is_dir:print(f"{prefix}└── {self.folder_symbol}{item}")else:print(f"{prefix}└── {self.file_symbol}{item}")else:if is_dir:print(f"{prefix}├── {self.folder_symbol}{item}")else:print(f"{prefix}├── {self.file_symbol}{item}")# 遞歸處理子目錄if is_dir:child_printer = DirectoryPrinter(root_dir=path,show_hidden=self.show_hidden,depth=self.depth + 1,max_depth=self.max_depth,indent_symbol=self.indent_symbol,folder_symbol=self.folder_symbol,file_symbol=self.file_symbol)child_printer.print_directory()
這部分代碼實現了遞歸打印的核心邏輯,使用不同的符號區分文件和文件夾,以及區分是否是最后一項。
使用示例
通過交互式界面配置打印參數:
def main():root_directory = input("請輸入要打印的目錄路徑: ") or os.getcwd()hide_hidden_files = input("是否隱藏隱藏文件? (y/n): ").lower() != 'y'max_depth = input("請輸入最大遞歸深度 (留空表示無限制): ").strip() or Noneauto_print = input("是否自動打印目錄結構? (y/n): ").lower() == 'y'printer = DirectoryPrinter(root_dir=root_directory,show_hidden=hide_hidden_files,max_depth=max_depth)printer.print_directory()
輸出效果
示例輸出可能如下:
├── / dir1
│ ├── - file1.txt
│ └── / subdir
│ └── - file2.txt
└── / dir2├── - file3.txt└── - file4.txt
附錄
import osclass DirectoryPrinter:def __init__(self, root_dir, show_hidden=False, depth=0, max_depth=None, indent_symbol='│ ', folder_symbol='/ ', file_symbol='- '):"""初始化目錄打印器:param root_dir: 指定要打印的目錄路徑:param show_hidden: 是否打印隱藏文件和文件夾(默認為 False):param depth: 當前遞歸深度(內部使用,用戶無需設置):param max_depth: 最大遞歸深度,None 表示無限制:param indent_symbol: 縮進符號:param folder_symbol: 文件夾前綴符號:param file_symbol: 文件前綴符號"""self.root_dir = root_dirself.show_hidden = show_hiddenself.max_depth = max_depthself.indent_symbol = indent_symbolself.folder_symbol = folder_symbolself.file_symbol = file_symbolself.depth = depthdef print_directory(self):"""打印目錄結構"""try:items = os.listdir(self.root_dir)except FileNotFoundError:print(f"指定的目錄 {self.root_dir} 不存在")returnexcept PermissionError:print(f"無法訪問目錄 {self.root_dir}")return# 過濾隱藏文件if not self.show_hidden:items = [item for item in items if not (item.startswith('.') and os.path.isfile(os.path.join(self.root_dir, item)))]# 遞歸打印目錄和文件for index, item in enumerate(sorted(items), start=1):path = os.path.join(self.root_dir, item)is_dir = os.path.isdir(path)# 根據當前深度和最大深度決定是否繼續遞歸if self.max_depth is not None and self.depth > self.max_depth:continue# 構建前綴prefix = self.indent_symbol * self.depthif index == len(items):if is_dir:print(f"{prefix}└── {self.folder_symbol}{item}")else:print(f"{prefix}└── {self.file_symbol}{item}")else:if is_dir:print(f"{prefix}├── {self.folder_symbol}{item}")else:print(f"{prefix}├── {self.file_symbol}{item}")# 遞歸處理子目錄if is_dir:child_printer = DirectoryPrinter(root_dir=path,show_hidden=self.show_hidden,depth=self.depth + 1,max_depth=self.max_depth,indent_symbol=self.indent_symbol,folder_symbol=self.folder_symbol,file_symbol=self.file_symbol)child_printer.print_directory()def main():"""主函數,用戶配置入口"""# 配置參數root_directory = input("請輸入要打印的目錄路徑: ") or os.getcwd() # 默認為當前目錄hide_hidden_files = input("是否隱藏隱藏文件? (y/n): ").lower() != 'y'max_depth = input("請輸入最大遞歸深度 (留空表示無限制): ").strip() or None # 無限制auto_print = input("是否自動打印目錄結構? (y/n): ").lower() == 'y'# 轉換為整數try:max_depth = int(max_depth) if max_depth else Noneexcept ValueError:print("最大遞歸深度必須為整數")return# 打印配置print("\n=== 配置 ===")print(f"根目錄: {root_directory}")print(f"隱藏文件和文件夾: {'是' if hide_hidden_files else '否'}")print(f"最大遞歸深度: {'無限制' if max_depth is None else max_depth}")# 初始化打印器printer = DirectoryPrinter(root_dir=root_directory,show_hidden=hide_hidden_files,max_depth=max_depth)# 開始打印if auto_print:print("\n=== 目錄結構 ===")printer.print_directory()else:input("\n按下回車鍵開始打印目錄結構...")print("\n=== 目錄結構 ===")printer.print_directory()# 程序主入口
if __name__ == "__main__":main()