我读到__init__
并没有创建对象(预留了内存)。
我找不到实际创建对象的人。 该对象创建在内部如何发生?
答案 0 :(得分:2)
当您在Python中键入类似MyClass()
的内容时,Python运行时将在__new__
上调用MyClass
,这应该构造一个对象;然后在新构造的对象上调用__init__
。因此,__new__
被称为“构造函数”,__init__
被称为“初始化程序”。此序列在Python外部进行编码(对于CPython,使用C语言编写)。请访问Python文档,以详细了解__new__
和__init__
。
答案 1 :(得分:2)
您可能正在寻找__new__
。
从Python的角度来看,假设您有一个直接继承自A
的类object
,那么发生的事情类似于以下内容:
A.__new__
方法被调用object.__new__
被呼叫,cls=A
A.__init__
方法,并使用从您的A.__new__
转发的参数示例:
class A():
def __new__(cls, *args, **kwargs):
print(f'__new__ called with args {args} and kwargs {kwargs}')
return super().__new__(cls) # object.__new__
def __init__(self, *args, **kwargs):
print(f'__init__ called with args {args} and kwargs {kwargs}')
# args are discarded
for key, arg in kwargs.items():
setattr(self, key, arg)
a_instance = A('arg', kwarg=1)
a_instance.kwarg
输出:
__new__ called with args ('arg',) and kwargs {'kwarg': 1}
__init__ called with args ('arg',) and kwargs {'kwarg': 1}
1
通常,__new__
不需要做任何事情,因为因为Python对象通常是可变的,所以在初始化实例属性和修改实例属性之间没有区别。
根据我的经验,覆盖__new__
的主要用例是从不可变类型(例如tuple
)继承。在这种情况下,您必须在创建时初始化所有实例属性,因此__init__
为时已晚。
答案 2 :(得分:2)
简而言之,创建对象的方法是__new__
,而__init__
只是初始化创建的对象。
但是,如果您想更深入地了解将要在python中创建对象的情况,请继续阅读。
在python 2.x中,python旧样式和新样式类中有两种类型的类。
class C: # A old-style class sample
pass
class C(object): # A old-style class sample
pass
在老式类中,没有__new__
方法,因此__init__
是构造函数。
但是,在python 3.x中,仅保留了新型类(与为类选择的定义无关,它将继承自基类“ Object”)。在新型类中,__new__
和__init__
方法均可用。 __new__
和__init__
分别是构造函数和初始值设定项,允许您覆盖它们两者(注意,在某些情况下,通常不需要覆盖__new__
方法例如定义元类等,因此在不需要时不要对其进行操作。)
最后,当要创建对象时,构造函数将在初始化之前被调用。
class A(object): # -> don't forget the object specified as base
def __new__(cls):
print "A.__new__ called"
return super(A, cls).__new__(cls)
def __init__(self):
print "A.__init__ called"
A()
输出将是:
A.__new__ called
A.__init__ called