您正在使用旧的Python版本;此错误消息已更新:
>>> object.__new__(testclass1, 56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
Python只会抱怨__init__
既不支持__new__
又不__init__
被覆盖的参数。例如,当您同时继承时object
。testclass1
适合这种情况,testclass3
不是因为它有一个__init__
方法。
这是为了支持实现不使用的不可变类型__init__
(object
在这种情况下将继承自该类型) 和 可变类型, 而 可变类型__new__
则不必在乎参数的__init__
期望值(通常是 更多的 参数)。
参见问题1683368,其中Guido van Rossum解释了他的动机。
该typeobject.c
源代码,有这样一段话:
您可能想知道为什么object.__new__()
只有 在object.__init__()
不被覆盖时才抱怨参数,反之亦然。
考虑用例:
当两个都不被覆盖时,我们希望听到对过多(即任何)参数的抱怨,因为它们的存在可能表明存在错误。
定义不可变类型时,我们可能仅覆盖__new__()
,因为__init__()
调用时太晚了,无法初始化不可变对象。由于__new__()
定义了类型的签名,因此不得不重写__init__()
以阻止它抱怨过多的参数将是一件痛苦的事情。
定义Mutable类型时,我们可能仅覆盖__init__()
。因此,这里有相反的推理:我们不想__new__()
为了阻止抱怨而不必重写。
当__init__()
被覆盖并且子类__init__()
调用时object.__init__()
,后者应该抱怨过多的参数;同上__new__()
。
用例2和3使得无条件检查多余的参数变得没有吸引力。解决所有四个用例的最佳解决方案如下:__init__()
抱怨过多的参数,除非__new__()
被覆盖__init__()
且未被覆盖(IOW,如果__init__()
被覆盖或__new__()
未被覆盖);对称地,__new__()
抱怨多余的参数,除非__init__()
被覆盖__new__()
且未被覆盖(IOW,如果__new__()
被覆盖或__init__()
未被覆盖)。
但是,为了向后兼容,这会破坏太多的代码。因此,在2.6中,当两种方法都被覆盖时,我们将 警告 过多的参数。对于所有其他情况,我们将使用上述规则。
请注意,该.__init__()
方法 仍会抱怨!创建实例时,__new__
和__init__
都被调用;你的代码仅调用__new__
直接和它 不会 调用__init__
!创建的实例testclass1
和testclass3
如果加上参数都失败:
>>> testclass1(56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters
>>> testclass3(56)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 1 argument (2 given)