__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__
Python 新手:有人知道 __init__(self) 做啥吗? (请简单解释!)[重复]