最可靠方式是调用BaseException.__subclasses__()递归遍历继承树,因其反映CPython运行时真实结构,比文档或help更全;except Exception捕不到SystemExit等退出异常,应避免except BaseException。

Python 异常类继承关系怎么查最可靠
直接看 BaseException 的 __subclasses__() 链,比翻文档或记忆更准——因为 CPython 源码里新增异常(比如 KeyboardInterrupt)未必全在文档“标准异常”表里列全,而 __subclasses__() 是运行时真实继承树。
实操建议:
- 在 Python 交互式环境里执行
BaseException.__subclasses__(),得到顶层子类(如SystemExit、KeyboardInterrupt、Exception) - 对每个子类再调用
__subclasses__(),递归展开(注意避开循环引用,Exception和BaseException本身不互为直接父子) - 别依赖
help(Exception)输出的“Subclasses”列表——它只显示模块级定义的类,漏掉动态生成的(如某些库注入的异常)
捕获 Exception 和 BaseException 的实际区别
用 except Exception: 捕不到 SystemExit、KeyboardInterrupt、GeneratorExit;但 except BaseException: 会捕到——这在写守护进程或 CLI 工具时极易出问题:比如你本想优雅退出,却因捕了 BaseException 把 Ctrl+C 给吞了,导致程序无法中断。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
- 脚本加了
except BaseException:后,Ctrl+C失效,必须kill -9 - 单元测试里用
self.assertRaises(BaseException)断言失败,因为测试框架本身抛的是AssertionError(继承自Exception),不是BaseException直系子类
正确做法:除非你在写解释器或信号拦截层,否则一律用 except Exception:;真要处理退出信号,显式捕 KeyboardInterrupt 或 SystemExit。
Python v2.4版chm格式的中文手册,内容丰富全面,不但是一本手册,你完全可以把她作为一本Python的入门教程,教你如何使用Python解释器、流程控制、数据结构、模板、输入和输出、错误和异常、类和标准库详解等方面的知识技巧。同时后附的手册可以方便你的查询。
raise 时不带参数和带 None 的行为差异
在 except 块里写 raise(无参数)会原样重抛当前异常,保留原始 traceback;写 raise None 是语法错误,Python 3.10+ 会报 SyntaxError: invalid syntax;而 raise e(其中 e 是捕获的异常实例)会创建新 traceback,丢失原始上下文。
使用场景与风险:
- 日志后透传异常:用
raise(空 raise),不要raise e - 想改写异常类型但保留 traceback:用
raise NewError(...) from e,触发异常链 -
raise e在多线程/协程中尤其危险——原始异常可能来自其他上下文,traceback 完全失真
自定义异常该继承 Exception 还是 RuntimeError
绝大多数情况继承 Exception 就够了。继承 RuntimeError 只在明确表示“程序运行时发生了未预期状态,且不属于 I/O、类型、逻辑等已有分类”时才合理——比如异步任务调度器检测到死锁,或 ORM 发现对象状态不一致。
性能与兼容性影响:
- 所有内置异常检查(如
isinstance(e, Exception))对Exception子类天然兼容;若继承RuntimeError,需额外确认下游是否只检查Exception - 某些框架(如 Flask 的错误处理器)默认只捕
Exception及其子类,不处理RuntimeError的子类,除非显式注册 - 别为了“显得更具体”而深挖继承链——
MyAppError继承Exception比继承ValueError更安全,除非你真要参与int()那类函数的错误语义
真正容易被忽略的是:异常类名末尾要不要加 Error 或 Exception。PEP 8 明确建议用 Error(如 ParseError),但很多主流库(requests、sqlalchemy)混用。统一就行,别在同一个项目里既有 ConnectionError 又有 TimeoutException。







