在Python中实现`Exception .__ str __()`

时间:2016-07-21 09:21:56

标签: python python-3.x exception

我从来没有完全理解Python中的异常处理(或者说任何语言都是诚实的)。我正在尝试自定义异常,并发现以下行为。

class MyError(Exception):
    def __init__(self, anything):
        pass

me = MyError("iiiiii")
print(me)

输出:

iiiiii

我认为print()会调用Exception.__str__()

基类Exception如何知道打印iiiiii?字符串"iiiiii"通过参数MyError传递给anything的构造函数,但anything根本没有存储在MyError的任何位置!

此外,MyError的构造函数不会调用其超类(Exception)的构造函数。那么,print(me)如何打印iiiiii

1 个答案:

答案 0 :(得分:1)

在Python 3中,BaseException类有一个__new__方法,用于存储self.args中的参数:

>>> me.args
('iiiiii',)

您没有覆盖__new__方法,只有__init__。您需要覆盖两者以完全阻止设置self.args,因为两个实现都乐意设置该属性:

>>> class MyError(Exception):
...     def __new__(cls, *args, **kw):
...         return super().__new__(cls)  # ignoring args and kwargs!
...     def __init__(self, *args, **kw):
...         super().__init__()           # again ignoring args and kwargs
...
>>> me = MyError("iiiiii")
>>> me
MyError()
>>> print(me)

>>> me.args
()

在Python 2中,异常不会实现__new__,并且您的示例不会打印任何内容。有关__new__方法添加的原因,请参见issue #1692335;基本上是为了避免__init__方法也不会调用super().__init__()的问题。

请注意,__init__不是构造函数;该实例已经由__new__构建。 __init__仅仅是初始化