pathlib.Path.rglob() 是专为递归匹配设计的方法,深度遍历子目录查找符合 glob 模式的文件(如 "*.py"),返回 Path 对象列表,支持直接调用 .open() 等方法;注意勿与仅查当前层的 glob() 混淆,且应避免手动拼接路径或错误转义。

pathlib.Path.rglob() 是最直接的解决方案
不用写递归函数,也不用拼接字符串路径,rglob() 就是专为这种场景设计的:从某个根目录开始,深度优先遍历所有子目录,匹配符合 glob 模式(如 "*.py" 或 "config.json")的文件。
常见错误是误用 glob() —— 它只查当前层级,不会进子目录;而 rglob() 的 r 就代表 recursive。
- 用法示例:
list(Path("/home/user/project").rglob("*.log")) - 返回的是
Path对象列表,不是字符串,可直接调用.open()、.read_text()等方法 - 注意路径开头不要带
**/——rglob("*.log")已隐含该语义;写成rglob("**/*.log")会重复展开,效率略低且行为不变
匹配带空格或特殊字符的文件名要小心转义
如果目标文件名含空格、括号或方括号(比如 my config (v2).txt),直接传入 rglob("my config (v2).txt") 可能失败——因为 glob 模式里空格无特殊含义,但 (、)、[、] 是通配符,会被解释为模式语法而非字面量。
- 安全做法是用
pathlib.PurePath构造后调用name属性比对:[p for p in root.rglob("*") if p.name == "my config (v2).txt"] - 或者用
fnmatch手动过滤:[p for p in root.rglob("*") if fnmatch(p.name, "my config (v2).txt")] - 避免用
rglob("my config (v2).txt")—— pathlib 不支持反斜杠转义 glob 元字符,该写法无效
大目录下性能差?加个 early-stop 条件
rglob() 默认遍历完整棵树,遇到海量小文件或深层嵌套时可能卡顿。如果你只需要找到第一个匹配项就停止,别用 list() 包裹整个结果。
立即学习“Python免费学习笔记(深入)”;
- 用
next(root.rglob("settings.py"), None)获取首个匹配项,没找到返回None - 需要前 N 个?用
itertools.islice(root.rglob("*.py"), 5) - 注意:
rglob()返回的是生成器,不触发遍历就不会耗时;一旦转成list或循环到底,就全扫一遍 - Windows 上访问受限目录(如
C:System Volume Information)会抛PermissionError,需手动捕获并跳过
跨平台路径拼接出错?别用字符串 +
有人习惯写 str(root) + "/src/" + filename,这在 Windows 下会因反斜杠导致路径失效;更糟的是混用 / 和 后,Path 构造失败或指向错误位置。
- 始终用
/运算符拼接:root / "src" / filename——pathlib.Path重载了该操作符,自动适配系统分隔符 - 绝对路径判断用
p.is_absolute(),不要用str(p).startswith("/")或str(p).startswith("\") - 相对路径转绝对路径统一用
p.resolve(),它会处理..、.和符号链接,比Path.cwd() / p更可靠
真正麻烦的不是找不到文件,而是遍历中途被权限拒绝打断,或者匹配逻辑被 glob 模式的隐含规则绕过。动手前先确认你要的是「精确文件名」还是「模糊模式」,再决定用 rglob 还是手动 iterdir + is_file 过滤。


















