Python3中IOError与FileNotFoundError是否可互换?
问题解答:IOError与FileNotFoundError的区别及捕获顺序问题
首先明确:这两个异常不能直接互换使用,你看到的“调换顺序后异常始终进入第一个块”的现象,是由Python 3中二者的继承关系决定的。
核心原因:Python 3的异常体系变化
在Python 3.3及以后的版本中:
FileNotFoundError是OSError的直接子类,专门用于捕获文件/路径不存在这类特定异常IOError已经被重命名为OSError(或成为OSError的别名),它的捕获范围宽泛得多——所有IO相关异常(包括文件不存在、权限不足、设备不可用等)都会被它捕获
当你尝试打开不存在的文件时,Python抛出的是FileNotFoundError:
- 如果
except IOError块写在前面,由于IOError等价于OSError(是FileNotFoundError的父类),父类异常的捕获块会优先捕获子类异常,所以会进入第一个块 - 如果调换顺序,把
except FileNotFoundError放在前面,这个更精确的子类异常会被优先捕获,不会走到后面的IOError块
二者的差异与适用场景
- FileNotFoundError:针对性极强,只处理“找不到文件/路径”的情况,适合明确要处理文件不存在场景的代码,能避免误捕获其他IO异常
- IOError(Python3中即OSError):覆盖所有IO操作相关的错误,比如权限错误(
PermissionError)、磁盘空间不足、设备未就绪等,范围远大于前者
举个例子,如果代码遇到文件权限不足的错误,FileNotFoundError的捕获块不会触发,而IOError块会正常捕获:
import errno try: stream = open("/root/secret_file", "rb") except FileNotFoundError as e: print("文件不存在") # 不会触发 except IOError as e: if e.errno == errno.EACCES: print("权限不足") # 会触发
总结
虽然在“文件不存在”这个特定场景下,调换两个捕获块的顺序都会让第一个块触发,但这不代表二者可以互换:
- 用
FileNotFoundError能更精准地处理目标异常,避免意外捕获其他IO错误 - 用
IOError则是兜底处理所有IO类异常,适合需要统一处理多种IO错误的场景
内容的提问来源于stack exchange,提问作者Ananth Raghuraman
相关产品推荐
相关产品推荐

