应过滤隐藏目录和虚拟环境:遍历中修改dirnames列表,排除以.开头及venv、env等;用relpath计算真实深度控制缩进;路径转小写连字符生成github兼容锚点;通过标记定位更新readme,避免覆盖原有内容。

用 os.walk() 遍历项目目录时,如何跳过隐藏文件和虚拟环境
直接调用 os.walk() 会遍历所有子目录,包括 .git、__pycache__、venv、.idea 等干扰项,导致生成的目录树冗长且无意义。
实操建议:在遍历前过滤掉以 . 开头的目录名,并显式排除常见虚拟环境路径:
- 检查
dirnames列表并原地修改(del或[:] =),不能只用continue,否则子目录仍会被递归进入 - 推荐写法:
for root, dirnames, filenames in os.walk(top):<br> dirnames[:] = [d for d in dirnames if not d.startswith('.') and d not in ('venv', 'env', '.venv', '__pycache__')] - 注意
os.walk()的topdown=True是默认行为,必须保持,否则过滤无效
生成 Markdown 目录树时,缩进层级怎么对应实际目录深度
很多人用字符串拼接 " " 或 "\t" 控制缩进,结果层级错乱——因为根目录深度为 0,但第一级子目录应显示为 - src/,不是 - - src/。
实操建议:用 os.path.relpath(path, start) 计算相对路径,再按 os.sep 分割得到真实深度:
- 设项目根为
project_root = os.getcwd(),对每个root调用relpath = os.path.relpath(root, project_root) - 若
relpath == '.',深度为 0;否则depth = len(relpath.split(os.sep)) - 每层用
" " * depth + "- " + basename + "/"(目录)或" " * (depth + 1) + "- " + filename(文件) - 避免用
root.count(os.sep)—— Windows 下drive:\path会导致计数错误
怎样让 README.md 里的目录结构支持点击跳转(锚点)
纯文本目录好看但没法点,用户仍得手动翻找。Markdown 锚点依赖文件名转义规则,Python 默认不处理,直接写 [src/](#src) 会 404。
实操建议:对路径做 GitHub 风格的锚点编码 —— 小写 + 连字符替换空格/斜杠/点,去掉非 ASCII 字符:
- 用正则
re.sub(r'[^\w\s-]', '', name)清理非法字符 - 再用
re.sub(r'[-\s]+', '-', name.strip()).lower()标准化 - 例如
tests/unit/test_utils.py→tests-unit-test-utils-py,最终生成:[tests/unit/test_utils.py](#tests-unit-test-utils-py) - 注意:GitHub 对锚点大小写敏感,务必统一转小写;中文路径建议跳过生成或提示警告,不强行转拼音
运行脚本后 README.md 被覆盖,怎么安全更新又不丢原有内容
直接 open('README.md', 'w') 会清空全文,如果原 README 有安装说明、作者信息等,就全没了。
实操建议:把目录结构插入到特定标记之间,比如 <!-- DIR-TREE:START --> 和 <!-- DIR-TREE:END -->:
- 读取原文件为字符串,用
re.split()或两次str.find()定位标记位置 - 只替换两标记之间的内容,其余部分原样保留
- 首次运行时若标记不存在,在文件末尾追加(或开头,按需),并带上注释说明用途
- 强烈建议加
--dry-run参数,先打印将要写入的内容,确认无误再落盘
目录结构工具真正的难点不在遍历或格式化,而在于“不破坏已有文档语义”——它本质是个文本编辑器,不是生成器。你得预判哪些行该留、哪些标记是人工维护的、哪些路径应该被忽略。一次写对不难,难的是下次项目结构调整后还能稳定跑通。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











