Python pathlib.Path.rglob 怎样排除构建目录
来源:17golang原创
时间:2026-10-26 04:16:47 461浏览 收藏
用 pathlib.Path.rglob() 扫描 Python 项目时,最容易出现的结果是:源码找到了,build、dist、__pycache__ 里的生成文件也一起进来了。稳定的处理方式不是把模式写得越来越复杂,而是把“递归匹配”和“目录排除”分成两层:先用 rglob 找到候选路径,再用 Path.parts 判断完整目录段。
官方文档:https://docs.python.org/3/library/pathlib.html#pathlib.Path.rglob
这样既保留了 Path 对不同操作系统路径的处理,也不会因为目录名只是某个字符串的一部分而误删文件。下面以“收集项目中的 Python 源文件”为例,整理一套可复用的筛选结构。
先把 rglob 的职责限定在递归匹配
rglob(pattern) 会从当前路径递归寻找符合模式的路径对象。它适合表达“我要哪些后缀”,例如 *.py;但它不是一个完整的排除配置器。把所有黑名单都塞进 glob 模式,遇到多级目录和平台差异时反而难读。
from pathlib import Path
root = Path("project")
# 这里只声明候选类型:递归找到所有 Python 文件。
candidates = root.rglob("*.py")
# rglob 返回 Path 对象,后续可以继续读取 parts、suffix 和 name。
for path in candidates:
print(path)
把 rglob 看成“输入候选路径”的入口后,真正的过滤条件就可以独立测试、独立扩展。

用 parts 排除完整目录段
不要用 "build" in str(path) 作为唯一判断。它可能把 build-tools 或文件名中带有 build 的路径误认为构建目录。Path.parts 会把路径拆成目录段,黑名单只命中独立段时才排除。
from pathlib import Path
EXCLUDED_DIRS = {"build", "dist", "__pycache__", ".venv"}
def is_source_file(path: Path) -> bool:
# 只排除完整路径段,避免误伤 build-tools 或 rebuild.py。
has_excluded_dir = any(part in EXCLUDED_DIRS for part in path.parts)
# 后缀判断保持简单,让排除规则和文件类型各自负责一件事。
return path.is_file() and path.suffix == ".py" and not has_excluded_dir
def collect_sources(root: Path) -> list[Path]:
# 先递归收集候选,再统一过滤,方便增加新的目录规则。
sources = (path for path in root.rglob("*.py") if is_source_file(path))
# 排序让构建日志、缓存键和后续处理顺序保持稳定。
return sorted(sources)
这里的两个判断层次很清楚:suffix 决定文件类型,parts 决定它是否位于被排除的目录。若只想跳过名为 build 的顶层目录,也可以把判断改成相对路径的第一段,但要先明确扫描根目录。

把筛选器做成可维护的收集函数
工程代码里建议让黑名单成为显式配置,而不是散落在多个生成器表达式中。上面的 collect_sources 还带来了三个好处:调用方得到普通的 list[Path],可以在需要时排序;过滤函数能单独测试;将来加入 tests、examples 等规则时只改集合。
如果项目允许目录名大小写变化,应先定义策略。Linux 路径通常区分大小写,Windows 常见文件系统可能不区分;不要未经决定就把所有路径统一小写,否则会掩盖真实文件名。更稳妥的做法是根据项目约定生成黑名单,或者只匹配仓库中实际约定的目录名。
几个容易漏掉的边界
- 空结果:没有符合条件的源码时返回空列表是正常结果,调用方不要把它当成异常。
- 符号链接:如果扫描范围包含链接目录,要按项目安全策略决定是否允许跟随;不要把它和普通目录排除混在一起。
- 相对路径:使用
parts前先确认黑名单针对的是绝对路径还是相对项目根的路径,避免根目录名称碰巧撞名。 - 稳定顺序:递归遍历的自然顺序不应当作为业务顺序,交给
sorted()明确固定结果。
可以把最终判断概括为:rglob 负责找到候选,suffix 负责类型,parts 负责目录边界,sorted 负责稳定输出。这样排除构建目录时,规则既直观,又不会随着项目目录层级增加而失控。
相关问题
Path.rglob("**/*.py") 和 Path.rglob("*.py") 有什么区别?
都用于递归查找时,优先使用更直接的 *.py 表达目标;关键差别不在排除目录,而在后续筛选是否清晰。
为什么不直接用 glob 排除目录?
复杂排除通常会让模式变得难以解释。把目录黑名单放到 parts 判断中,更容易测试和扩展。
只排除当前根目录下的 build 怎么写?
把路径转换成相对根目录后的 parts,只检查第一段是否为 build,不要对完整绝对路径做模糊字符串搜索。
-
346 收藏
-
235 收藏
-
158 收藏
-
479 收藏
-
172 收藏
-
276 收藏
-
473 收藏
-
488 收藏
-
257 收藏
-
419 收藏
-
115 收藏
-
378 收藏
-
文章 · python教程 | 1小时前 | TLS · python · 网络安全 · Python ssl.SSLContext TLS版本 minimum_version maximum_version399 收藏
-
353 收藏
-
256 收藏
-
137 收藏
-
446 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习