现代 Python 中如何正确定义自定义异常?

Python 自定义异常的标准做法是继承 Exception(或更具体的内置异常类),按需添加属性。本文给出规范写法、继承选择与常见误区。

最佳实践
现代 Python 中如何正确定义自定义异常?封面

标准做法:定义一个继承自 Exception 的新类,在 __init__ 中保存自定义属性。如果语义合适,优先继承更具体的内置异常(如 ValueError),调用方可以用更宽泛或更精确的 except 捕获。

基本写法

class MyException(Exception):
    def __init__(self, message):
        self.message = message
        super().__init__(message)

raise MyException("这是我的自定义异常")

调用 super().__init__(message) 是个好习惯:保证 str(exc)args 等标准行为正常工作。

选择合适的基类

class InvalidConfigError(ValueError):
    """配置值非法时抛出"""

继承具体异常的好处:调用方原有的 except ValueError 依然能捕获它,向后兼容。

项目级异常体系

常见模式是定义一个项目基类,再派生具体异常:

class AppError(Exception):
    """本项目所有异常的基类"""

class DatabaseError(AppError):
    pass

class ConfigError(AppError):
    pass

这样调用方可以 except AppError 一网打尽,也可以精确捕获子类。

常见问题(FAQ)

Q:能从 BaseException 继承吗?
A:不要。BaseExceptionKeyboardInterruptSystemExit 的基类,继承它会导致异常被 except Exception 漏捕,破坏常规错误处理逻辑。

Q:自定义异常需要实现 str 吗?
A:一般不需要。把信息传给 Exception.__init__ 就有默认的字符串表示;只有想定制展示格式时才重写。

Q:异常信息很多怎么办?
A:在 __init__ 中接收多个参数存为属性(如 self.codeself.payload),捕获方可以读取这些属性做结构化处理,比往 message 字符串里塞信息更可维护。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台