为什么对象.__ new__在这两种情况下工作不同 [英] Why does or rather how does object.__new__ work differently in these two cases

查看:114
本文介绍了为什么对象.__ new__在这两种情况下工作不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python版本:'2.7.3(默认值,2013年4月10日,06:20:15)\\\
[GCC 4.6.3]'

Python version: "'2.7.3 (default, Apr 10 2013, 06:20:15) \n[GCC 4.6.3]'"

我有这个:

>>> class testclass1(object):
    ...     pass
    ... 

>>> class testclass2(object):
    ...     def __init__(self,param):
    ...             pass
    ... 

>>> a = object.__new__(testclass1, 56)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object.__new__() takes no parameters

>>> b = object.__new__(testclass2, 56)

>>> b
    <__main__.testclass2 object at 0x276a5d0>

更有趣!与上述testclass1的结果比较。

Some more fun! Compare with results of testclass1 above.

>>> class testclass3(object):
    ...     def __init__(self):
    ...             pass
    ... 

>>> c = object.__new__(testclass3, 56)

>>> c
    <__main__.testclass3 object at 0x276a790>

>>> c1 = object.__new__(testclass3)

>>> c1
    <__main__.testclass3 object at 0x276a810>

我的问题是 c> object__new __ 在这两种情况下的行为不同?
另外注意,错误在第一种情况下是误导的,因为在第二种情况下 object .__ new __ 确实最后接受一个参数。

My question is how does (not why does) object__new__ behave differently in these two cases? Also notice the error is kind of misleading in the first case because in the second case object.__new__ does end up taking an argument!.

推荐答案

object .__ new __ object .__ init __ 通过一个仔细构造的条件迷宫,在某些情况下允许过多的争论,在其他人提出错误,并在非常具体的一个警告。 实施检查的代码很容易遵循,但背后的推理可能仍然是不可改变的,没有澄清评论

Both object.__new__ and object.__init__ go through a carefully constructed maze of conditions that allow excess arguments in some cases, raise an error in others, and raise a warning in a very specific one. The code that implements the checks is easy enough to follow, but the reasoning behind it would likely remain inscrutable without this elucidating comment:


您可能会想知道为什么 object .__ new __()关于参数
对象.__初始化__()不会被覆盖,反之亦然。

You may wonder why object.__new__() only complains about arguments when object.__init__() is not overridden, and vice versa.

用例:


  1. 当两者都被覆盖时,我们想听到关于过多(即任何)

  1. When neither is overridden, we want to hear complaints about excess (i.e., any) arguments, since their presence could indicate there's a bug.

当定义一个Immutable类型时,我们很可能只覆盖 __ new __(),因为 __ init __()被调用太晚以初始化一个
Immutable对象。因为 __ new __()定义了
类型的签名,所以必须重写 __ init __()

When defining an Immutable type, we are likely to override only __new__(), since __init__() is called too late to initialize an Immutable object. Since __new__() defines the signature for the type, it would be a pain to have to override __init__() just to stop it from complaining about excess arguments.

定义一个Mutable类型时,我们很可能只覆盖 __ init __()。所以这里的反向推理适用:我们不想让
重写 __ new __(),只是为了阻止它抱怨。

When defining a Mutable type, we are likely to override only __init__(). So here the converse reasoning applies: we don't want to have to override __new__() just to stop it from complaining.

__ init __()被覆盖,子类 __ init __()调用 object .__ init __(),后者应该抱怨过多的
参数; ditto for __ new __()

When __init__() is overridden, and the subclass __init__() calls object.__init__(), the latter should complain about excess arguments; ditto for __new__().

使用案例2和3使得无条件检查
多余参数不具吸引力。解决所有四个用例
的最佳解决方案如下: __ init __()抱怨过多的参数,除非
__ new __ )被重写,并且 __ init __()不被重写(IOW,if
__ init __ c $ c>被重写或 __ new __()不被覆盖);
对称, __ new __()抱怨过多的参数,除非重写
__ init __() __ new __()未被覆盖(IOW,如果
__ new __ c> __ init __()不会被覆盖。)

Use cases 2 and 3 make it unattractive to unconditionally check for excess arguments. The best solution that addresses all four use cases is as follows: __init__() complains about excess arguments unless __new__() is overridden and __init__() is not overridden (IOW, if __init__() is overridden or __new__() is not overridden); symmetrically, __new__() complains about excess arguments unless __init__() is overridden and __new__() is not overridden (IOW, if __new__() is overridden or __init__() is not overridden).

但是,为了向后兼容,
因此,在2.6中,当两个
方法都被覆盖时,我们将警告多余的参数;对于所有其他情况,我们将使用上述规则。

However, for backwards compatibility, this breaks too much code. Therefore, in 2.6, we'll warn about excess arguments when both methods are overridden; for all other cases we'll use the above rules.

这篇关于为什么对象.__ new__在这两种情况下工作不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆