我试图了解如何使用这两种方法。我知道那__new__
是用来创建对象的,而__init__
用来初始化的。但我不确定创建对象时会发生什么。
这是否意味着
__new__
并且__init__
必须具有相同的参数?如果我不使用相同的参数会怎样?
我试图了解如何使用这两种方法。我知道那__new__
是用来创建对象的,而__init__
用来初始化的。但我不确定创建对象时会发生什么。
这是否意味着__new__
并且__init__
必须具有相同的参数?
如果我不使用相同的参数会怎样?
是的。
你会得到一个错误。
(从技术上讲,__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)
两种方法都将传递(几乎)相同的参数集,因此通常它们具有匹配的签名(相同的参数集)。
我在那里说“几乎”,因为__new__
方法是作为第一个参数传递给类的,而__init__
方法是传递方法的结果__new__
;新创建的实例。
在python中,可以使用“通配符”参数;*args
and (**keyword
参见What do *args and **kwargs mean?),这意味着要么__new__
或__init__
可以使用它们来仅命名一些传入的参数。
当签名不匹配时会发生什么(考虑到通配符参数)?你得到的结果与将参数传递给任何签名与传入的参数不匹配的 python 可调用对象相同;你得到一个例外。