初始化器 vs 构造函数

17
我听说Python中的__init__函数不是构造函数,而是初始化函数。实际上,__new__函数才是构造函数。它们之间的区别在于__init__函数在对象创建后调用,而__new__函数则在其之前调用。我说的对吗?你能更好地解释一下它们之间的区别,以及为什么我们需要同时使用__new____init__吗?

2
请查看此链接:https://dev59.com/3XRB5IYBdhLWcg3wSVUI - Vinkal
__init__ 是其他面向对象编程语言(尤其是Java和C++)通常称为“构造函数”的直接等价物。据我所知,这些语言实际上没有任何直接等价于 __new__ 的东西。但可能正是因为“构造函数”等效物并不真正构造任何东西(C++或Java的“构造函数”也是如此),Python倾向于将这两者都称为实际方法名称,而不是称之为“构造函数”中的任何一个。 - lvc
3个回答

25

实质上,__new__ 负责创建实例(因此,可以准确地说它是构造函数,正如您所指出的),而 __init__ 确实是一种初始化实例状态的方式。例如,考虑以下代码:

class A(object):

    def __new__(cls):
        return object.__new__(cls)

    def __init__(self):
        self.instance_method()

    def instance_method(self):
        print 'success!'

newA = A()
请注意,__init__ 接收参数 self,而 __new__ 接收类 (cls)。由于 self 是实例的引用,这应该让你很清楚地知道实例在 __init__ 被调用时已经被创建了,因为它会传递实例。也可以准确地调用实例方法,因为实例已经被创建。

至于你的第二个问题,在我的经验中很少需要使用 __new__。当然,有些情况下可能需要更高级的技术来使用 __new__,但这种情况很少见。一个臭名昭著的例子是人们可能想使用 __new__ 来创建 Singleton 类(无论这是否是一种好的技术,不过这并不是重点)。

无论如何,你基本上可以控制实例化的过程,以及在你特定情况下可能意味着什么。


3
__init__ 是以已构建好的对象实例为第一个参数进行调用的(通常称为 self,但这只是一个参数名称)。
相反地,__new__ 是通过将作为第一个参数进行调用,并预计返回一个实例(稍后将传递给 __init__)。
例如,这允许 __new__ 返回一个已存在的实例,用于基于值的不可变对象,其中身份不应扮演任何角色。

当你说__new__被调用并将作为第一个参数传递时,你指的是哪个类? - HelloGoodbye
@HelloGoodbye:正在构建的对象的类。这可以是您放置__new__的同一类,也可以是从中派生的类(如果既没有派生类也没有在此类之前列出的其他基类定义了__new__)。 - 6502

1
考虑阅读有关类自定义的文档以获取更多细节。
根据此,这些方法的使用方式如下:__new__() 用于创建对象,__init__() 用于自定义它。
正如6502所指出的那样,__new__ 是静态方法的特殊情况,并将类作为其参数,而__init__ 获取由__new__生成的对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接