惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
博客园 - Franky
J
Java Code Geeks
V
Visual Studio Blog
G
Google Developers Blog
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美
The GitHub Blog
The GitHub Blog
腾讯CDC
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
博客园 - 【当耐特】
IT之家
IT之家
I
InfoQ
U
Unit 42
C
Check Point Blog
Martin Fowler
Martin Fowler

博客园 - Swizard

还在被框架绑架?一文看懂“六边形架构”,让你的核心业务稳如泰山! 逐行解剖:扒开 Lovable Agent 源码,看顶级 AI 是如何“思考”与“动刀”的 还在无脑堆砌提示词?三分钟看懂 Vercel v0 价值千万的 System Prompt 底层逻辑 OpenClaw+OpenViking + NVIDIA API 配置教程 拒绝“挤牙膏”!用苏格拉底提示法,让 AI 从“复读机”进化为“咨询顾问” 别再写丑陋的 Shell 脚本了:用 Gum 给你的终端穿上“高定西装” 告别 sudo 滥用!用 gosu 优雅解决 Docker 容器权限的“千古难题” 拒绝视觉噪音:用“数据墨水比”法则重塑你的专业图表 告别 Git Stash:用 Git Worktree 实现多任务并行,效率起飞! 手机里的 Linux 实验室:Termux 让你随时随地开启“黑客”模式 拒绝“隐形”!用 JSON-LD 让你的网页在 Google 搜索结果中“自带光环” ⚔️ Google SGE vs. Perplexity:一场内容争夺战,两套生存法则 SEO 已死?拥抱 AEO/GEO:如何让 AI 主动“推荐”你的网站 Python 重构神器:告别 ast 模块的痛苦,三行代码搞定复杂批量修改 告别笨重的 For 循环:用 xargs 打造 Linux 命令行流水线神器 告别“断网即崩溃”:像存档游戏一样管理你的终端会话(Tmux 终极入门) 沉默的观察者:Multi-Agent 架构如何实现“零指令”主动服务? 杀死那个提示词框:揭秘“意图识别 + 动态组装”的幕后逻辑 UI 设计如何落地“Boss Mode”?告别聊天框的四个交互法则 用 100 倍 Token 换取 10% 体验:关于 AI Agent 的“暴力美学”
别再手写递归找文件了!用 Python rglob 一行代码搞定海量搜索
Swizard · 2026-01-06 · via 博客园 - Swizard

1. 拒绝“面条代码”:你还在用 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 模块中的核武器,能让你用一行代码,优雅地完成上述所有工作。


2. 概念拆解:地毯式搜索

生活类比:找遥控器

为了理解 globrglob 的区别,我们来想象一个生活场景:你在家里找电视遥控器。

  • 普通的 glob (Globbing): 这就好比你站在客厅中央,只用眼睛扫视当前房间的桌面和沙发。如果遥控器在卧室或者抽屉里,你是找不到的。glob 只匹配当前目录,不进入子目录。

  • rglob (Recursive Glob): 这就是 rglob 的威力——递归(Recursive)。这就好比你雇佣了一支专业的搜查队。他们不仅看客厅,还会打开每一扇门(进入子目录),拉开每一个抽屉(进入更深层目录),直到把整个家翻个底朝天,找出所有符合特征的目标。

逻辑图解

想象一棵倒立的树(文件系统):

  1. 起点:你指定的根目录。

  2. 动作rglob 会自动沿着树枝向下生长,触达每一个末梢(文件)。

  3. 筛选:在遍历的同时,它直接过滤出符合你设定模式(Pattern)的文件。


3. 动手实战:三行代码的魔法

让我们抛弃 os 模块,拥抱现代化的 pathlib

Hello World:找出所有 Python 文件

假设你的项目结构很深,你想列出所有的 .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 行核心代码,逻辑扁平,语义清晰。


4. 进阶深潜:你必须知道的细节

虽然 rglob 很强,但在生产环境中使用时,有几个关键点需要注意。

A. 通配符的艺术

rglob 支持标准的 Unix shell 风格通配符:

  • rglob('*.jpg'):所有 JPG 图片。

  • rglob('test_*.py'):所有以 test_ 开头的 Python 测试文件。

  • rglob('**/config.yaml'):这也行?是的!其实 rglob('*') 等同于 glob('**/*')。在 pathlib 中,** 本身就代表递归目录。

B. 性能陷阱:不要搜全盘!

千万不要在根目录(如 /C:\)下运行 Path('/').rglob('*')。 因为 rglob 会尝试遍历整个文件系统。如果你的目录包含 node_modules (前端噩梦) 或 .git 文件夹,文件数量可能高达数十万。

最佳实践: 尽量缩小搜索范围,或者在遍历时手动排除特定目录(虽然 rglob 本身不带排除参数,你可能需要在循环中加个 if 判断)。

C. 想要列表怎么办?

前面提到 rglob 返回的是生成器。如果你确定文件数量不多,想直接要一个列表:

# 强制转换为列表
all_images = list(Path('./images').rglob('*.png'))
print(f"一共找到了 {len(all_images)} 张图片")

5. 总结与延伸

核心知识点

  1. pathlib 是未来:尽量用 pathlib.Path 替代 os.path

  2. rglob 是递归神器:它能自动穿透多层文件夹查找文件,无需手写循环。

  3. 生成器机制:它是惰性求值的,省内存,适合处理大量文件。