“在现代Python中声明自定义异常的正确方法?”
这很好,除非您的异常实际上是一种更具体的异常类型:class MyException(Exception):
pass
或者更好(也许是完美的),而不是pass给出一个文档字符串:class MyException(Exception):
"""Raise for my specific kind of exception"""
子类异常子类Exception
所有内置的、非系统退出的异常都是从这个类派生出来的。所有用户定义的异常也应该从这个类派生出来。
这意味着如果您的异常是一种更具体的异常类型,它是一个子类,而不是泛型。Exception(其结果将是您仍然可以从Exception如医生所建议)。另外,您至少可以提供一个docstring(而不是强制使用pass关键字):class MyAppValueError(ValueError):
"""Raise when my specific value is wrong"""
使用自定义设置属性__init__..避免将dict作为位置参数传递,您的代码的未来用户将感谢您。如果您使用不推荐的消息属性,则您自己分配它将避免DeprecationWarning:class MyAppValueError(ValueError):
"""Raise when a specific subset of values in context of app is wrong"""
def __init__(self, message, foo, *args):
self.message = message # without this you may get DeprecationWarning
# Special attribute you desire with your Error,
# perhaps the value that caused the error?:
self.foo = foo
# allow users initialize misc. arguments as any other builtin Error
super(MyAppValueError, self).__init__(message, foo, *args)
你真的没必要写你自己的__str__或__repr__..内置的很好,你的合作继承确保你能使用它。
对最上面答案的批评也许我错过了这个问题,但为什么不呢?class MyException(Exception):
pass
同样,上面的问题是,为了捕获它,您必须指定它的名称(如果在其他地方创建,就导入它),或者捕获异常(但是您可能还没有准备好处理所有类型的异常,并且应该只捕获您准备处理的异常)。与下面类似的批评,但除此之外,这不是初始化的方式super,你会得到一个DeprecationWarning如果您访问消息属性:编辑:若要覆盖某些内容(或传递额外的args),请执行以下操作:class ValidationError(Exception):
def __init__(self, message, errors):
# Call the base class constructor with the parameters it needs
super(ValidationError, self).__init__(message)
# Now for your custom code...
self.errors = errors这样,您就可以将错误消息块传递给第二个Param,并在后面使用e.Error进行处理。
它还要求传入两个参数(除了self)不多也不差。这是一个有趣的限制,未来的用户可能不会理解。
我将演示这两个错误:>>> ValidationError("foo", "bar", "baz").messageTraceback (most recent call last):
File "", line 1, in
ValidationError("foo", "bar", "baz").messageTypeError: __init__() takes exactly 3 arguments (4 given)
>>> ValidationError("foo", "bar").message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6"foo"
与之相比:>>> MyAppValueError("foo", "FOO", "bar").message"foo"