为什么Python 2.x中带参数的object.__new__正常工作而Python 3.3+中不行?
为什么下面的代码在Python 2.x中运行正常,而在Python 3.3及以上版本中却不行呢:
class TestA(object):
def __new__(cls, e):
return super(TestA, cls).__new__(TestB, e)
class TestB(TestA):
def __init__(self, e):
print(self, e)
TestA(1)
Python 2.7.6的输出结果:
(<__main__.TestB object at 0x7f6303378ad0>, 1)
Python 3.1.5的输出结果:
__main__:3: DeprecationWarning: object.__new__() takes no parameters
<__main__.TestB object at 0x7f2f69db8f10> 1
Python 3.2.3和3.2.5的输出结果:
<__main__.TestB object at 0xcda690> 1
Python 3.3.5和3.4.1的输出结果:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __new__
TypeError: object() takes no parameters
2 个回答
1
你可以像下面这样把 __init__ 函数移动到 TestA:
class TestA(object):
def __new__(cls, e):
return super(TestA, cls).__new__(TestA)
def __init__(self, e):
print(self, e)
TestA(1)
注意,TestB 这个类不再需要了。
注意,在调用 object.__new__ 时,'e' 这个参数被省略了。object 类的 new 函数只需要一个类作为参数,而在重写的 __new__ 函数中(这里是 TestA 的),任何额外的参数会自动传递给传给 object.__new__ 的类的构造函数(在这个例子中也是 TestA 的构造函数 __init__)。
9
object.__new__
一直以来都不会处理多余的参数,并且从 Python 2.6 开始就会发出一个 DeprecationWarning
(弃用警告)。
你在 2.7 和 3.2 版本中没有看到这个 DeprecationWarning
的原因是,从这两个版本开始,DeprecationWarning
默认是被隐藏的;如果你使用 python -Wd
或者设置 PYTHONWARNINGS=default
,那么你就能看到这个警告了。
在 Python 3.3 中,DeprecationWarning
被转变成了一个错误。
在任何版本的 Python 中,正确的写法是让 TestA.__new__
忽略多余的参数:
class TestA(object):
def __new__(cls, e):
return super(TestA, cls).__new__(TestB)
因为 TestB
是从 TestA
继承而来的,所以多余的参数会被传递给 TestB.__init__
。