os.walk()返回(root, dirs, files)三元组,root为当前目录路径,dirs和files仅为当前层级的子目录名与文件名列表(非完整路径),需用os.path.join()拼接;dirs可就地修改以跳过子目录遍历。

os.walk() 返回值结构怎么理解
它返回的是一个三元组 (root, dirs, files),每次迭代对应一个目录层级。很多人误以为 dirs 是完整路径,其实只是当前 root 下的子目录名列表(不带路径),files 同理。
常见错误现象:拼接路径时直接用 root + filename,结果在 Windows 上变成 C:\a\b\c.txt 这种错误路径;或在 Linux 上漏掉 / 导致路径断裂。
- 永远用
os.path.join(root, name)拼接路径,别手写斜杠 -
dirs可被就地修改——删掉某个子目录名,os.walk()就不会进入它(用于跳过特定目录) - 如果想只遍历到某一层级,需手动计数,
os.walk()本身不支持深度限制
怎么只获取所有文件路径(不含目录)
最常用需求:拿到全部文件的绝对路径。关键不是“过滤”,而是别把 dirs 当成文件处理——有人会误把 dirs 里的名字也塞进结果列表。
使用场景:批量读取日志、扫描配置文件、计算总文件大小。
import os
all_files = []
for root, dirs, files in os.walk('/path/to/start'):
for f in files:
all_files.append(os.path.join(root, f))
- 别写
for d in dirs: all_files.append(...)——那是目录,不是文件 - 如果需要绝对路径,开头先用
os.path.abspath()规范起始路径,避免相对路径干扰 - 注意符号链接:默认
os.walk()不跟随软链;如需跟随,加参数followlinks=True,但可能引发循环引用
怎么跳过某些目录(比如 .git、__pycache__)
靠修改 dirs 列表实现,这是 os.walk() 提供的唯一可控入口。不能靠 continue 跳过当前轮次,因为那只会跳过当前 root 的 files 处理,不影响后续递归。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
性能影响:提前剔除大目录(如 node_modules)能显著减少遍历耗时和内存占用。
- 在每次循环开头就清理
dirs:dirs[:] = [d for d in dirs if d not in ('.git', '__pycache__', 'venv')] - 必须用切片赋值
dirs[:],直接dirs = [...]不生效——os.walk()绑定的是原列表对象 - 正则匹配?别在这儿做,太慢;先用字符串判断,再按需扩展
os.walk() 和 pathlib.Path.rglob() 哪个更合适
如果项目已用 pathlib,且只需简单通配(如 **/*.py),rglob() 更简洁;但涉及条件过滤、路径改造、中途终止等逻辑,os.walk() 更直接可控。
兼容性影响:pathlib 在 Python 3.4+ 原生支持,但旧代码或需兼容 3.3 的场景仍得用 os.walk()。
-
os.walk()返回的是字符串路径,pathlib返回Path对象——后者调.stat()或.read_text()更方便 -
rglob()无法跳过某类目录(比如遇到node_modules就停止向下),只能事后过滤,效率低 - 跨平台路径处理上,
pathlib更健壮,但os.walk()配合os.path也能做到,只是多写两行
真正复杂点在于混合场景:既要跳过某些目录,又要按文件类型分组统计,还要记录修改时间——这时候硬套 rglob() 反而绕弯,不如老老实实用 os.walk() 控制每一步。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










