自定义异常应继承 Exception 而非 BaseException,因后者包含 SystemExit、KeyboardInterrupt 等不应被常规捕获的系统级异常;except: 等价于 except BaseException:,会静默吞掉 Ctrl+C,应改用 except Exception:;唯一合理使用 BaseException 的场景是实现底层退出机制。
BaseException 是所有异常的根,但你不该直接继承它
绝大多数自定义异常应该继承
,而不是
。因为
包含了
、
、
这类“程序控制流级”的异常,它们本就不该被常规
捕获——否则会吞掉用户按 Ctrl+C 的意图,或让
失效。
继承
的自定义类,会被
捕获,但也会意外捕获
,导致脚本无法用 Ctrl+C 中断
是
的子类,专为“程序运行时错误”设计,是所有业务异常的合理父类
标准库中只有极少数系统级异常(如
)直接继承
,这是有意为之的隔离
try-except 里写 except Exception: 和 except: 的实际区别
等价于
,它会捕获一切,包括你绝对不该捕获的退出信号。而
明确排除了
、
等,这才是安全的兜底写法。
写
后,按 Ctrl+C 没反应,脚本卡死,因为
被静默吞掉了
仍会漏掉
,但至少保留了中断能力;如果真要拦截退出,应显式写
生产环境禁止使用裸
;CI/CD 流水线可加 pylint 规则
拦截
什么时候必须用 BaseException?几乎不用,但有个例外
唯一合理场景:你要实现一个类似
或
的底层退出机制,且需要绕过所有常规异常处理逻辑。普通业务代码、Web 视图、数据处理函数里,完全不需要碰
。
写 CLI 工具时想模拟
行为?直接调
,别自己 raise
子类
测试中想触发“不可被捕获的退出”?用
,它不走 Python 异常机制
误把
当成“更高级的异常”来用,是常见误解;它不是“更强”,而是“更底层、更危险”
自定义异常的推荐写法和命名习惯
继承
,名字以
结尾,按模块分组。不要为了“看起来专业”而往上提继承层级,
就是你的起点和终点。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
下载
立即学习
“
Python免费学习笔记(深入)
”;
正确:
;错误:
避免空异常类;至少加一句
文档字符串
如果需区分客户端错误和服务端错误,用不同子类(如
/
),但都继承
,不要另起炉灶
Python 3.11+ 支持
,但它仍是
的子类,不影响上述原则
真正容易被忽略的是:很多人以为“捕得越全越健壮”,结果把
当成保险丝用,反而切掉了程序最基础的响应能力。异常体系不是靠继承深度体现权威,而是靠边界清晰来保障可控性。
ExceptionBaseExceptionBaseExceptionSystemExitKeyboardInterruptGeneratorExitexcept:sys.exit()BaseExceptionexcept BaseException:KeyboardInterruptExceptionBaseExceptionSystemExitBaseExceptionexcept:except BaseException:except Exception:SystemExitKeyboardInterruptexcept:KeyboardInterruptexcept Exception:SystemExitexcept SystemExit:except:bare-exceptsys.exit()os._exit()BaseExceptionsys.exit()sys.exit()BaseExceptionos._exit(1)BaseExceptionExceptionErrorExceptionclass ConfigLoadError(Exception): passclass ConfigLoadError(BaseException): pass"""Failed to load config from YAML."""ClientErrorServerErrorExceptionExceptionGroupExceptionBaseException