You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pathlib对快速变化目录递归glob时出现FileNotFoundException如何处理

为什么会抛出异常而不是自动跳过

pathlib的rglob方法默认假设遍历期间目录结构是静态稳定的,没有内置动态目录变化场景的容错逻辑:它执行递归匹配时,会先拉取当前目录下的所有子条目列表,识别到子目录后就会尝试进入该目录继续递归,如果该目录刚好在「识别到存在」和「实际进入遍历」的间隙被删除,就会直接抛出FileNotFoundException。
标准库没有默认做自动跳过的处理,是为了避免静默吞掉非竞争场景下的真实目录访问错误,这种目录频繁增删的动态场景属于非常规使用场景,需要用户主动加容错逻辑。

精简规避方案

推荐两种可直接落地的方案,按精简程度排序:

方案1:迭代器异常捕获包装(最简,仅需6行代码)

写一个通用的迭代异常捕获包装器,直接包裹rglob的返回值即可,不需要修改原有遍历逻辑:

def safe_iter(glob_iter):
    iterator = iter(glob_iter)
    while True:
        try:
            yield next(iterator)
        except StopIteration:
            return
        except FileNotFoundError:
            # 跳过已被删除的目录,继续遍历剩余条目
            continue

使用方式直接替换原有调用即可:

from pathlib import Path
p = Path()
# 原写法 list(p.rglob('*')) 替换为下面的写法
list(safe_iter(p.rglob('*')))

方案2:自定义递归遍历(可控性更高)

如果需要兼容更多异常场景(比如权限不足、软链接异常等),可以自己实现带异常捕获的递归遍历:

from pathlib import Path
import os

def safe_rglob(root: Path, pattern: str = "*"):
    # 先返回当前层级匹配的结果
    yield from root.glob(pattern)
    # 遍历子目录,加异常捕获
    for entry in os.scandir(root):
        if entry.is_dir(follow_symlinks=False):
            try:
                yield from safe_rglob(Path(entry.path), pattern)
            except (FileNotFoundError, PermissionError):
                # 遇到异常目录直接跳过
                continue

内容的提问来源于stack exchange,提问作者nonForgivingJesus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:36:02