__new__ 和 __init__ [重复]

Posted

技术标签:

【中文标题】__new__ 和 __init__ [重复]【英文标题】:__new__ and __init__ [duplicate] 【发布时间】:2012-08-01 03:52:58 【问题描述】:

可能重复:Python's use of __new__ and __init__?

我正在尝试了解如何使用这两种方法。我知道__new__ 用于创建对象,而__init__ 用于初始化。但我不确定创建对象时会发生什么。

    是不是说__new____init__的参数必须一样?

    如果我不使用相同的参数会怎样?

【问题讨论】:

why defined '__new__' and '__init__' all in a class部分回答 __new____init__ 做不同的事情并有不同的参数。 This question 提供了一个很好的概述。 【参考方案1】:

    是的。

    你会得到一个错误。

(技术上__new__的第一个参数是类,而__init__的第一个参数是实例。但是,它们必须都能够接受相同的参数仍然是正确的,因为,除了第一个参数,传递给__init__ 的参数与传递给__new__ 的参数相同。)

>>> class Foo(object):
...     def __new__(cls, x):
...         return super(Foo, cls).__new__(cls)
...     
...     def __init__(self, x, y):
...         pass
>>> Foo(1)
Traceback (most recent call last):
  File "<pyshell#260>", line 1, in <module>
    Foo(1)
TypeError: __init__() takes exactly 3 arguments (2 given)
>>> Foo(1, 2)
Traceback (most recent call last):
  File "<pyshell#261>", line 1, in <module>
    Foo(1, 2)
TypeError: __new__() takes exactly 2 arguments (3 given)

【讨论】:

那么*args**kw 呢?此外,通过将 x 参数传递给 super(..).__new__,您将触发 DeprecationWarning,从而混淆 OP。 这就是为什么我说“必须都能够接受相同的论点”。确实,您可以使用 *args**kwargs 来获得不完全相同的参数列表,但对于任何函数都是如此。重要的一点是相同的参数被传递给两个函数,所以它们必须能够接受相同的东西。 (感谢您注意到 DeprecationWarning 的问题,我已解决。)【参考方案2】:

这两种方法将传递(几乎)相同的参数集,因此通常它们具有匹配的签名(相同的参数集)。

我在这里说“几乎”,因为__new__ 方法作为第一个参数传递给类,而__init__ 方法传递__new__ 方法的结果;新创建的实例。

在python中,你可以使用“通配符”参数; *args**keyword(参见 What do *args and **kwargs mean?),这意味着 __new____init__ 可以使用它们来仅命名传入的参数中的一些

当签名不匹配时会发生什么(考虑通配符参数)?你得到的结果与将参数传递给任何签名与传入的参数不匹配的 python 可调用对象相同;你得到一个例外。

【讨论】:

以上是关于__new__ 和 __init__ [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python(和 Python C API):__new__ 与 __init__

__init__.py 在同一目录中找不到模块[重复]

Python 新手:有人知道 __init__(self) 做啥吗? (请简单解释!)[重复]

从列表 Python 错误中打印 __init__ 对象 [重复]

Python元类的__new__方法中的奇怪行为[重复]

为啥不导入 Python [重复]