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

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

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

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

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

【问题讨论】:

标签: python


【解决方案1】:
  1. 是的。

  2. 你会得到一个错误。

(技术上__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 可调用对象相同;你得到一个例外。

【讨论】:

    猜你喜欢
    • 2011-04-04
    • 2015-10-24
    • 2018-11-11
    • 2011-06-19
    • 2019-10-24
    • 2022-10-14
    • 2014-03-01
    • 2021-11-23
    • 2016-11-26
    相关资源
    最近更新 更多