最可靠方式是调用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。