在现代Python中声明自定义异常类的正确方法是什么?我的主要目标是遵循其他异常类所具有的任何标准,以便(例如)我在异常中包含的任何额外字符串都由捕捉到异常的任何工具打印出来。
我所说的“现代Python”是指在Python2.5中运行,但对于Python2.6和Python3.*的工作方式来说是“正确的”。我所说的“自定义”是指一个异常对象,它可以包含有关错误原因的额外数据:一个字符串,也可能是与异常相关的其他任意对象。
我被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
BaseException对名为message的属性具有特殊含义,这似乎很疯狂。我从PEP-352中了解到,这个属性在2.5中确实有特殊的含义,他们正试图贬低它,所以我想这个名字(以及这个名字)现在被禁止了?呃。
我还模糊地意识到Exception有一些神奇的参数参数,但我从未知道如何使用它;我在网上发现的许多讨论都表明,他们试图在Python 3中取消args。
更新:两个答案建议重写__init__和__str__/__unicode__/__repr_。这似乎需要很多打字,是吗?
查看如果使用一个或多个属性(省略了回溯),默认情况下异常是如何工作的:
>>> raise Exception('bad thing happened')
Exception: bad thing happened
>>> raise Exception('bad thing happened', 'code is broken')
Exception: ('bad thing happened', 'code is broken')
因此,您可能希望有一种“异常模板”,以兼容的方式作为异常本身工作:
>>> nastyerr = NastyError('bad thing happened')
>>> raise nastyerr
NastyError: bad thing happened
>>> raise nastyerr()
NastyError: bad thing happened
>>> raise nastyerr('code is broken')
NastyError: ('bad thing happened', 'code is broken')
这个子类可以很容易地完成
class ExceptionTemplate(Exception):
def __call__(self, *args):
return self.__class__(*(self.args + args))
# ...
class NastyError(ExceptionTemplate): pass
如果您不喜欢默认的类似元组的表示,只需将__str__方法添加到ExceptionTemplate类,如:
# ...
def __str__(self):
return ': '.join(self.args)
你会有
>>> raise nastyerr('code is broken')
NastyError: bad thing happened: code is broken
查看如果使用一个或多个属性(省略了回溯),默认情况下异常是如何工作的:
>>> raise Exception('bad thing happened')
Exception: bad thing happened
>>> raise Exception('bad thing happened', 'code is broken')
Exception: ('bad thing happened', 'code is broken')
因此,您可能希望有一种“异常模板”,以兼容的方式作为异常本身工作:
>>> nastyerr = NastyError('bad thing happened')
>>> raise nastyerr
NastyError: bad thing happened
>>> raise nastyerr()
NastyError: bad thing happened
>>> raise nastyerr('code is broken')
NastyError: ('bad thing happened', 'code is broken')
这个子类可以很容易地完成
class ExceptionTemplate(Exception):
def __call__(self, *args):
return self.__class__(*(self.args + args))
# ...
class NastyError(ExceptionTemplate): pass
如果您不喜欢默认的类似元组的表示,只需将__str__方法添加到ExceptionTemplate类,如:
# ...
def __str__(self):
return ': '.join(self.args)
你会有
>>> raise nastyerr('code is broken')
NastyError: bad thing happened: code is broken