









os.walk 吗?你是否遇到过这种场景:你需要在一个拥有几十个子文件夹、成百上千个文件的庞大项目中,找出所有的 .log 日志文件进行分析。
作为一个硬核程序员,你的第一反应可能是祭出 os.walk 并在里面嵌套两层 for 循环,或者更惨——自己写一个递归函数(Recursion)去遍历文件夹。
写完之后,代码可能是这样的:
import os
# 传统的痛苦写法
target_files = []
for root, dirs, files in os.walk('my_project'):
for file in files:
if file.endswith('.log'):
target_files.append(os.path.join(root, file))
这段代码能跑,但它并不优雅。它把“遍历逻辑”和“筛选逻辑”混在了一起,不仅难读,而且容易写错。
今天我要介绍的 rglob,就是为了终结这种痛苦而生的。 它是 Python 3.4 引入的 pathlib 模块中的核武器,能让你用一行代码,优雅地完成上述所有工作。
为了理解 glob 和 rglob 的区别,我们来想象一个生活场景:你在家里找电视遥控器。
普通的 glob (Globbing): 这就好比你站在客厅中央,只用眼睛扫视当前房间的桌面和沙发。如果遥控器在卧室或者抽屉里,你是找不到的。glob 只匹配当前目录,不进入子目录。
rglob (Recursive Glob): 这就是 rglob 的威力——递归(Recursive)。这就好比你雇佣了一支专业的搜查队。他们不仅看客厅,还会打开每一扇门(进入子目录),拉开每一个抽屉(进入更深层目录),直到把整个家翻个底朝天,找出所有符合特征的目标。
想象一棵倒立的树(文件系统):
起点:你指定的根目录。
动作:rglob 会自动沿着树枝向下生长,触达每一个末梢(文件)。
筛选:在遍历的同时,它直接过滤出符合你设定模式(Pattern)的文件。
让我们抛弃 os 模块,拥抱现代化的 pathlib。
假设你的项目结构很深,你想列出所有的 .py 文件。
from pathlib import Path
# 1. 定义起点(当前目录)
current_dir = Path('.')
# 2. 发动 rglob 引擎
# 这里的 '*.py' 就是我们要找的特征
python_files = current_dir.rglob('*.py')
# 3. 打印结果
for file_path in python_files:
print(file_path)
代码解析:
Path('.'):这是面向对象的文件路径写法,比字符串路径更智能。
.rglob('*.py'):核心所在。r 代表 Recursive(递归)。它告诉 Python:“去在这个目录及其所有子目录中,找到后缀是 .py 的家伙。”
返回值:注意,这里返回的不是一个死列表,而是一个生成器(Generator)。这意味着即使有 100 万个文件,它也不会瞬间撑爆你的内存,而是你通过 for 循环要一个,它给一个。
os 模块?os 模块写法:需要 5-6 行,逻辑嵌套。
rglob 写法:1 行核心代码,逻辑扁平,语义清晰。
虽然 rglob 很强,但在生产环境中使用时,有几个关键点需要注意。
rglob 支持标准的 Unix shell 风格通配符:
rglob('*.jpg'):所有 JPG 图片。
rglob('test_*.py'):所有以 test_ 开头的 Python 测试文件。
rglob('**/config.yaml'):这也行?是的!其实 rglob('*') 等同于 glob('**/*')。在 pathlib 中,** 本身就代表递归目录。
千万不要在根目录(如 / 或 C:\)下运行 Path('/').rglob('*')。 因为 rglob 会尝试遍历整个文件系统。如果你的目录包含 node_modules (前端噩梦) 或 .git 文件夹,文件数量可能高达数十万。
最佳实践: 尽量缩小搜索范围,或者在遍历时手动排除特定目录(虽然 rglob 本身不带排除参数,你可能需要在循环中加个 if 判断)。
前面提到 rglob 返回的是生成器。如果你确定文件数量不多,想直接要一个列表:
# 强制转换为列表
all_images = list(Path('./images').rglob('*.png'))
print(f"一共找到了 {len(all_images)} 张图片")
pathlib 是未来:尽量用 pathlib.Path 替代 os.path。
rglob 是递归神器:它能自动穿透多层文件夹查找文件,无需手写循环。
生成器机制:它是惰性求值的,省内存,适合处理大量文件。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。