我从来没有完全理解 Python(或者老实说,任何语言)中的异常处理。我正在试验自定义异常,并发现了以下行为。
class MyError(Exception):
def __init__(self, anything):
pass
me = MyError("iiiiii")
print(me)
输出:
iiiiii
我假设 print()
调用 Exception.__str__()
。
基类Exception
怎么知道打印iiiiii
?字符串 "iiiiii"
通过参数 anything
传递给了 MyError
的构造函数,但是 anything
不是完全存储在 MyError
中的任何位置!
此外,MyError
的构造函数不会调用其父类(super class)(异常)的构造函数。那么,print(me)
是如何打印出 iiiiii
的呢?
最佳答案
在 Python 3 中,BaseException
类有一个 __new__
方法将参数存储在 self.args
中:
>>> me.args
('iiiiii',)
您没有覆盖 __new__
方法,仅覆盖了 __init__
。您需要覆盖 both 以完全防止设置 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__
并且您的示例不会打印任何内容。参见 issue #1692335至于为什么要添加__new__
方法;基本上是为了避免像您这样的问题,其中 __init__
方法也不会调用 super().__init__()
。
请注意 __init__
不是构造函数;到那时,实例已经由 __new__
构建。 __init__
只是初始化程序。
关于python - `Exception.__str__()`在Python中的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38500098/