应直接用 try/except 捕获 FileNotFoundError,而非预检路径存在性;它专用于文件或目录不存在场景,常见于 open() 等 I/O 操作,捕获时需避免宽泛异常掩盖真实错误。

直接用 try/except 捕获 FileNotFoundError
Python 3.3+ 中,FileNotFoundError 是 OSError 的子类,专门用于文件或目录不存在的场景。它不会自动抛出——必须显式触发,比如调用 open()、os.stat() 或 pathlib.Path().resolve() 等操作时路径无效才会触发。
最常见写法就是把文件操作包进 try 块,单独捕获 FileNotFoundError,避免误吞其他 I/O 错误(如权限拒绝、磁盘满):
try:
with open("config.json") as f:
data = json.load(f)
except FileNotFoundError:
print("配置文件 config.json 未找到,使用默认配置")
data = {"debug": False}
- 不要用空的
except:或宽泛的except OSError:,否则会掩盖PermissionError或IsADirectoryError等真实问题 - 如果同时要处理“文件不存在”和“是目录而非文件”,可并列捕获:
except (FileNotFoundError, IsADirectoryError): -
FileNotFoundError在 Windows 和 Linux 下行为一致,无需额外适配
检查路径存在前是否需要先调用 os.path.exists()?
不需要。主动检查再操作(“check-then-act”)在多线程/多进程环境下有竞态风险:路径可能在 exists() 返回 True 后瞬间被删除,导致后续 open() 仍抛出 FileNotFoundError。更可靠的做法是直接操作 + 异常捕获(“easier to ask for forgiveness than permission”,EAFP)。
- 用
os.path.exists()或pathlib.Path().exists()只适合做预判展示(如 UI 提示),不适合替代异常处理 - 若需区分“文件不存在”和“不是普通文件”,建议捕获
FileNotFoundError后再用pathlib.Path().is_file()判断,而不是提前查类型 - 注意:
os.path.exists()对符号链接失效路径也返回False,而open()抛的是FileNotFoundError,语义一致
pathlib 中如何优雅处理 FileNotFoundError?
pathlib 的多数方法(如 read_text()、read_bytes()、open())同样抛 FileNotFoundError,捕获方式完全一致。但它的 Path().exists() 和 Path().is_file() 不抛异常,适合组合使用。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
from pathlib import Path
p = Path("data.csv")
try:
content = p.read_text(encoding="utf-8")
except FileNotFoundError:
print(f"{p} 不存在,跳过处理")
content = ""
-
Path().read_text()内部仍调用open(),所以异常类型不变 - 避免链式调用如
p.resolve().read_text():一旦resolve()失败(路径不存在或循环软链),抛的是FileNotFoundError或FileExistsError,需单独捕获 -
Path().open()返回标准 file object,和内置open()行为一致,可直接用于上下文管理
为什么有时捕获不到 FileNotFoundError?
常见原因不是语法错,而是异常根本没发生——操作本身不触发该异常。例如:os.listdir("missing_dir") 抛 FileNotFoundError,但 glob.glob("missing/*.py") 只返回空列表,从不抛异常;shutil.copy("src", "dst") 在 src 不存在时才抛,而 dst 目录不存在则可能抛 FileNotFoundError 或 NotADirectoryError,取决于具体路径层级。
-
glob.glob()和pathlib.Path().glob()默认静默失败,返回空结果,不能靠捕获FileNotFoundError来判断模式是否匹配 -
shutil.move()对源路径不存在抛FileNotFoundError,但目标父目录不存在时抛FileNotFoundError(Linux)或OSError(Windows),行为不统一 - 第三方库(如
pandas.read_csv())通常封装了底层 open,但可能将FileNotFoundError转为自己的异常(如FileNotFoundError或pandas.errors.EmptyDataError),需查文档确认
真正要抓的永远是实际执行 I/O 的那一行,而不是外围逻辑。异常没被捕获,八成是那行根本没运行到。

















