Python pathlib.Path.rglob 怎样排除构建目录
用 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,不要对完整绝对路径做模糊字符串搜索。
Python csv.DictReader 自定义 fieldnames 读取无表头文件
- 上一篇
- Python csv.DictReader 自定义 fieldnames 读取无表头文件
- 下一篇
- Python re.Match.groupdict 怎样读取命名分组
-
- 文章 · python教程 | 1小时前 | 文件处理 · 标准库 · python · Python 编码 文本流 TextIOWrapper reconfigure
- Python TextIOWrapper.reconfigure 怎样在不重开文件时切换编码
- 276浏览 收藏
-
- 文章 · python教程 | 1小时前 | python · pathlib · Python pathlib 目录边界 Path.is_relative_to 路径判断
- Python pathlib.Path.is_relative_to 怎样判断路径是否位于指定目录
- 473浏览 收藏
-
- 文章 · python教程 | 1小时前 | 正则表达式 · python · Python re 命名分组 Match.groupdict
- Python re.Match.groupdict 怎样读取命名分组
- 488浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python csv.DictReader 自定义 fieldnames 读取无表头文件
- 257浏览 收藏
-
- 文章 · python教程 | 1小时前 |
- Python functools.cache 怎样判断是否适合缓存无参函数
- 419浏览 收藏
-
- 文章 · python教程 | 1小时前 | TLS · python · 网络安全 · Python ssl.SSLContext TLS版本 minimum_version maximum_version
- Python ssl.SSLContext 怎样限制允许的 TLS 版本
- 399浏览 收藏
-
- 文章 · python教程 | 1小时前 | python · 文件系统 · Python 文件遍历 DirEntry os.scandir
- Python os.scandir 怎样减少目录遍历中的属性查询
- 353浏览 收藏
-
- 文章 · python教程 | 1小时前 | python · 异步编程 · Python asyncio TaskGroup ExceptionGroup
- Python asyncio.TaskGroup 怎样在任务组结束时集中处理异常
- 256浏览 收藏
-
- 文章 · python教程 | 15小时前 | 并发 · 数组 · python · Python multiprocessing shared_memory 进程间数组
- shared_memory 怎样共享进程间数组
- 137浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 697次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 707次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 777次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 738次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 571次使用
-
- go格式“占位符”输入输出 类似python的input
- 2023-01-19 346浏览
-
- Golang如何调用Python代码详解
- 2023-01-07 235浏览
-
- Go filepath.WalkDir 如何跳过隐藏目录:SkipDir、DirEntry 与遍历剪枝
- 2026-08-30 158浏览
-
- Go filepath.WalkDir 怎么跳过隐藏目录并继续遍历
- 2026-09-07 479浏览
-
- Go filepath.WalkDir SkipDir 和返回错误的区别是什么
- 2026-09-11 172浏览

