Python遍历文件夹递归找文件:pathlib与os.walk两种写法
用Python递归遍历文件夹查找指定类型文件,pathlib.rglob和os.walk两种写法对比,支持按文件名后缀过滤,完整代码。
场景痛点
电脑里存了几年的资料,想找出所有的PDF文件,或者某个名字带"合同"的Word文档藏在哪层目录里。手动一层层点开文件夹找,目录深一点就翻不到底。用Python写个递归遍历脚本,指定根目录和过滤条件,几秒列出全部匹配文件的完整路径。
用到的库
pathlib # 标准库,写法一
os # 标准库,写法二(os.walk)
完整代码
from pathlib import Path
import os
def find_files_by_pathlib(root_dir: str, suffix: str = None, keyword: str = None) -> list:
"""
写法一:用pathlib.rglob递归查找文件
:param root_dir: 根目录
:param suffix: 文件后缀过滤,如 '.pdf';None表示全部
:param keyword: 文件名包含的关键字;None表示不过滤
"""
root = Path(root_dir)
results = []
# rglob 递归匹配所有文件
for file in root.rglob('*'):
if not file.is_file():
continue
if suffix and file.suffix.lower() != suffix.lower():
continue
if keyword and keyword.lower() not in file.name.lower():
continue
results.append(str(file.resolve()))
return results
def find_files_by_oswalk(root_dir: str, suffix: str = None) -> list:
"""
写法二:用os.walk递归遍历(兼容老项目)
"""
results = []
for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
if suffix and not filename.lower().endswith(suffix.lower()):
continue
full_path = os.path.join(dirpath, filename)
results.append(full_path)
return results
if __name__ == "__main__":
# 找出D盘Documents下所有PDF,且文件名含"合同"
matches = find_files_by_pathlib(
root_dir="D:/Documents",
suffix=".pdf",
keyword="合同"
)
print(f"找到 {len(matches)} 个文件:")
for p in matches:
print(p)
代码讲解
Path.rglob('*'):递归匹配所有文件和目录。rglob是recursive glob的缩写,相当于glob('**/*')。现代Python代码推荐这种写法,链式调用简洁。file.is_file():判断当前路径是不是文件(排除目录本身)。rglob会把目录也列出来,必须过滤。file.suffix:文件后缀,如.pdf。file.name:带后缀的文件名。组合起来可以同时按后缀和文件名关键词过滤。os.walk(root_dir):返回三元组(当前目录路径, 子目录列表, 文件列表)。每往下走一层,自动yield一次。老项目里常见,性能和rglob差不多。file.resolve():把相对路径转成绝对路径,方便后续直接打开或复制。
运行结果
脚本遍历D:/Documents所有子目录,打印出所有后缀为.pdf且文件名包含"合同"的文件完整路径,例如:
找到 3 个文件:
D:\Documents\2024\采购合同.pdf
D:\Documents\2025\销售合同_甲方.pdf
D:\Documents\归档\2023\房屋租赁合同.pdf
注意事项
- 遍历整个磁盘根目录(如
C:/)会非常慢,因为要读系统目录和回收站。建议限定在具体业务目录。 - 遇到权限不足的目录会抛PermissionError。生产脚本建议在循环里加try/except跳过无权限目录。
- 符号链接(软链接)默认不会递归跟随,避免循环引用。需要跟随的话pathlib用
follow_symlinks=True(Python 3.13+)。

更新时间:2026-09-14 21:16:00