Python实现5级目录文件递归遍历的优雅方案?os.walk遍历异常问题
Hey there! Let's clear up a common misunderstanding first: os.walk() absolutely traverses all levels of directories recursively, not just child and grandchild levels. The issue you're seeing is actually in how you're processing the root, dirs, and files variables in your loop—not with os.walk() itself.
问题出在哪?
Looking at your os.walk code, the logic for pairing directories and files is incorrect:
import os rootPath = '/path/to/my/folder/test' print '###### using os.walk ######' for root, dirs, files in os.walk(rootPath): print 'directory - ' + " ".join(dirs) for d in dirs: for f in files: if not f.startswith('.'): print 'directory - ' + d + ' file - ' + f
Here, files refers to files in the current root directory, not in the subdirectories listed in dirs. So when root is the fourth directory, you're incorrectly linking in_fourth.txt (from fourth) to the fifth subdirectory. When root reaches fifth, dirs is empty, so your inner loop never runs—hence in_fifth.txt never gets printed. This has nothing to do with os.walk failing to traverse into fifth.
正确的 os.walk 实现
To properly traverse all levels and display the structure (including in_fifth.txt), use this adjusted code:
import os rootPath = '/path/to/my/folder/test' print('###### Fixed os.walk implementation ######') for root, dirs, files in os.walk(rootPath): # Calculate depth relative to the root path depth = root.replace(rootPath, '').count(os.sep) indent = '-' * (depth + 1) # Print current directory print(f'{indent}{os.path.basename(root)}') # Print non-hidden files in the current directory for f in files: if not f.startswith('.'): print(f'{indent}-{f}')
This will correctly recurse into fifth and print in_fifth.txt, just like your nested isdir approach.
更优雅的替代方案
Your nested os.path.isdir approach works, but it's hardcoded to 5 levels—this is inflexible and messy if you ever need to adjust the depth. Here are two better options:
1. 递归函数(灵活控制深度)
This approach is clean, readable, and lets you easily limit traversal depth:
import os def traverse_dir(path, current_depth=0, max_depth=5): indent = '-' * (current_depth + 1) for entry in os.listdir(path): entry_path = os.path.join(path, entry) print(f'{indent}{entry}') # Only recurse if we haven't hit max depth if os.path.isdir(entry_path) and current_depth < max_depth: traverse_dir(entry_path, current_depth + 1, max_depth) rootPath = '/path/to/my/folder/test' print('\n\n\n###### Recursive traversal (max depth 5) ######') traverse_dir(rootPath)
2. 使用 pathlib(Python 3.4+)
The pathlib module makes directory traversal even more intuitive:
from pathlib import Path rootPath = '/path/to/my/folder/test' root = Path(rootPath) print('\n\n\n###### Pathlib recursive traversal ######') for entry in root.rglob('*'): # Calculate depth relative to root depth = len(entry.relative_to(root).parts) indent = '-' * depth print(f'{indent}{entry.name}') # To limit to 5 levels: print('\n\n\n###### Pathlib with max depth 5 ######') for entry in root.rglob('*'): depth = len(entry.relative_to(root).parts) if depth <= 5: indent = '-' * depth print(f'{indent}{entry.name}')
总结
os.walkdoes traverse all directory levels—your original code had a logic error, not a limitation in the function.- Nested
isdirchecks are brittle; use recursive functions orpathlibfor cleaner, more maintainable code. - Both recursive functions and
pathliblet you easily control the maximum traversal depth (like your requirement of 5 levels).
内容的提问来源于stack exchange,提问作者jerrythebum

