捕获 FileNotFoundError 的标准写法是 except FileNotFoundError:,因其精准匹配文件缺失场景,避免误吞权限、磁盘满等其他 I/O 异常;预检 os.path.exists() 易引发竞态条件,Python 官方推荐 EAFP 原则——直接操作并捕获异常。

捕获 FileNotFoundError 的标准写法
Python 3.12 中文件不存在时抛出的异常类型没变,仍是 FileNotFoundError(它是 OSError 的子类)。直接用 except FileNotFoundError: 最精准,避免误吞其他 I/O 错误。
常见错误是写成 except IOError: 或笼统的 except Exception:——前者在 3.12 中已不推荐(IOError 是 OSError 的别名,但语义模糊),后者可能掩盖权限拒绝、磁盘满等真实问题。
示例:
try:
with open("config.json", "r") as f:
data = json.load(f)
except FileNotFoundError:
print("配置文件 config.json 未找到,使用默认配置")
data = {"timeout": 30}
为什么不能只靠 os.path.exists() 预检?
预检查路径存在再打开,看似稳妥,但在多线程/多进程或 NFS 等场景下极易触发竞态条件(race condition):检查时文件存在,真正 open() 时已被删除或移动。
更可靠的做法是「EAFP 原则」(Easier to Ask for Forgiveness than Permission):直接操作,捕获异常。这是 Python 官方推荐的惯用法。
如果确实需要预检(比如仅做提示而不打开),注意:os.path.exists() 对符号链接失效,应改用 os.path.isfile();且它不检查读权限,open() 仍可能因权限失败。
-
os.path.isfile("path")比os.path.exists("path")更准确(排除目录) - 预检 + 打开之间仍有时间窗口,不能替代异常捕获
- 若需同时确认存在性和可读性,用
os.access(path, os.R_OK),但仍有微小窗口
open() 的 mode 参数对异常类型的影响
不同打开模式下,文件不存在时的异常一致,都是 FileNotFoundError,但触发时机和上下文有差异:
librosa 是一个用于音频和音乐分析的 Python 库。它提供了特征提取、频谱分析、节拍跟踪、起始检测和音频可视化的工具,基于 NumPy 和 SciPy 构建,用于科学音频计算。
-
"r"(默认):文件不存在 → 立即抛FileNotFoundError -
"x"(独占创建):文件已存在 → 抛FileExistsError(注意不是FileNotFoundError) -
"a"或"w":文件不存在会自动创建,不抛异常(除非路径中上级目录不存在,此时抛FileNotFoundError)
所以,如果你本意是“读取现有文件”,必须用 "r" 模式并捕获 FileNotFoundError;若用 "a",即使文件不存在也不会报错,但后续 read() 会失败(因为追加模式默认不可读)。
处理嵌套路径中的缺失目录(非文件)
当你要 open("logs/app.log", "w") 但 logs/ 目录不存在时,抛出的仍是 FileNotFoundError,但根源是目录缺失,不是文件缺失。
此时捕获 FileNotFoundError 后,可选择创建父目录:
import os
<p>try:
with open("logs/app.log", "a") as f:
f.write("log entry\n")
except FileNotFoundError as e:
if "logs" in str(e):
os.makedirs("logs", exist_ok=True)</p><h1>重试或直接写入</h1><pre class="brush:php;toolbar:false;"> with open("logs/app.log", "a") as f:
f.write("log entry\n")
更通用的做法是提前用 os.makedirs(os.path.dirname(path), exist_ok=True) 创建所有中间目录,但这只适用于写操作;读操作仍必须依赖异常捕获——因为无法预知用户会读哪个路径。
真正容易被忽略的是:FileNotFoundError 的 args 字段里包含原始路径字符串,但不同系统格式不同(Windows 有驱动器号,Linux 有前导斜杠),直接解析 str(e) 不可靠。建议用 os.path.dirname(path) 和 os.path.basename(path) 显式拆分路径做判断。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










