您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

为什么object .__ new__在这三种情况下工作不同

为什么object .__ new__在这三种情况下工作不同

您正在使用旧的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__被覆盖的参数。例如,当您同时继承时objecttestclass1适合这种情况,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__!创建的实例testclass1testclass3如果加上参数都失败:

>>> 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)

唯一的区别在于,testclass1这是该object()抱怨的方法,而不是自定义的特定错误__init__

其他 2022/1/1 18:31:22 有623人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶