我从来没有完全理解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
?
答案 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__
仅仅是初始化。