在现代 Python 中声明自定义异常类的正确方法是什么?我的主要目标是遵循其他异常类具有的任何标准,以便(例如)我在异常中包含的任何额外字符串都可以由捕获异常的任何工具打印出来。
我所说的“现代Python”是指可以在Python 2.5中运行的东西,但对于Python 2.6和Python 3.*的做事方式来说是“正确的”。我所说的“自定义”是指可以包含有关错误原因的额外数据的对象:一个字符串,也可能是与异常相关的其他任意对象。Exception
我被 Python 2.6.2 中的以下弃用警告绊倒了:
>>> class MyError(Exception):
... def __init__(self, message):
... self.message = message
...
>>> MyError("foo")
_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
对于名为 .我从 PEP-352 中收集到该属性在 2.5 中确实具有特殊含义,他们试图弃用,所以我想这个名字(而且只有一个)现在被禁止了?呸。BaseException
message
我也模糊地意识到它有一些神奇的参数,但我从来不知道如何使用它。我也不确定这是做事的正确方式;我在网上找到的很多讨论都表明他们试图在Python 3中取消args。Exception
args
更新:两个答案建议覆盖 和 //。这似乎很多打字,有必要吗?__init__
__str__
__unicode__
__repr__
网友回答:
使用现代 Python 例外,您不需要滥用 ,或覆盖或/或其中任何一个。如果在引发异常时只希望提供信息性消息,请执行以下操作:.message
.__str__()
.__repr__()
class MyException(Exception):
pass
raise MyException("My hovercraft is full of eels")
这将给出以 结尾的回溯。MyException: My hovercraft is full of eels
如果你想从异常中获得更大的灵活性,你可以传递一个字典作为参数:
raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})
但是,在一个块中获取这些细节有点复杂。详细信息存储在属性中,该属性是一个列表。您需要执行以下操作:except
args
try:
raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})
except MyException as e:
details = e.args[0]
print(details["animal"])
仍然可以将多个项目传递给异常并通过元组索引访问它们,但强烈建议不要这样做(甚至打算在不久前弃用)。如果您确实需要不止一条信息,并且上述方法对您来说还不够,那么您应该按照教程中的说明进行子类化。Exception
class MyError(Exception):
def __init__(self, message, animal):
self.message = message
self.animal = animal
def __str__(self):
return self.message
网友回答:
也许我错过了这个问题,但为什么不呢:
class MyException(Exception):
pass
要覆盖某些内容(或传递额外的参数),请执行以下操作:
class ValidationError(Exception):
def __init__(self, message, errors):
# Call the base class constructor with the parameters it needs
super().__init__(message)
# Now for your custom code...
self.errors = errors
这样,您就可以将错误消息的字典传递给第二个参数,并在以后使用 .e.errors
在 Python 2 中,你必须使用这种稍微复杂的形式:super()
super(ValidationError, self).__init__(message)
网友回答:
“在现代 Python 中声明自定义异常的正确方法是什么?”
这很好,除非您的异常确实是一种更具体的异常类型:
class MyException(Exception):
pass
或者更好(也许是完美的),而不是给出一个文档字符串:pass
class MyException(Exception):
"""Raise for my specific kind of exception"""
从文档中
Exception
所有内置的非系统退出异常都派生自此类。 所有用户定义的异常也应派生自此类
。
这意味着,如果您的异常是一种更具体的异常类型,请对该异常进行子类化而不是泛型(结果将是你仍然按照文档的建议派生)。此外,您至少可以提供文档字符串(并且不被迫使用关键字):Exception
Exception
pass
class MyAppValueError(ValueError):
'''Raise when my specific value is wrong'''
设置您自己使用自定义 .避免将字典作为位置参数传递,代码的未来用户会感谢您。如果使用已弃用的消息属性,则自己分配该属性将避免:__init__
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
同样,上述问题在于,为了捕获它,您必须专门命名它(如果在其他地方创建,则导入它)或捕获异常,(但您可能没有准备好处理所有类型的异常,您应该只捕获您准备处理的异常)。与下面的批评类似,但除此之外,这不是通过初始化的方法,如果您访问 message 属性,您将获得一个:super
DeprecationWarning
编辑:要覆盖某些内容(或传递额外的参数),请执行以下操作:
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
这样您就可以将错误消息的字典传递给第二个参数,并在稍后使用 e.errors 访问它
它还需要传入两个参数(除了 .)不多也不少。这是一个有趣的约束,未来的用户可能不会欣赏。self
直接地说 – 它违反了利斯科夫的可替代性。
我将演示这两个错误:
>>> ValidationError('foo', 'bar', 'baz').message
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
ValidationError('foo', 'bar', 'baz').message
TypeError: __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'
模板简介:该模板名称为【Python 中声明自定义异常类的正确方法是什么?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【Python】栏目查找您需要的精美模板。