初始化器与构造器[重复]

Posted

技术标签:

【中文标题】初始化器与构造器[重复]【英文标题】:Initializer vs Constructor [duplicate] 【发布时间】:2015-05-01 17:36:07 【问题描述】:

我听说python中的__init__函数不是构造函数,它是一个初始化器,实际上__new__函数是构造函数,不同的是__init__函数是在创建对象之后调用的和之前调用的__new__。我对吗?你能更好地解释一下区别吗?为什么我们需要__new____init__

【问题讨论】:

查看此链接:***.com/questions/674304/pythons-use-of-new-and-init __init__ is 直接等同于其他 OO 语言(尤其是 Java 和 C++)倾向于称为“构造函数”的内容。 AFAIK 这些语言并没有真正任何直接等同于__new__。但可能正是因为“构造函数”等价物并没有真正构造任何东西(C++ 或 Java 的“构造函数”也没有),Python 倾向于将它们都称为实际的方法名称,而不是调用 either “构造函数”。 【参考方案1】:

本质上,__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 类(然而,这是否是一种好技术并不是重点)。

无论好坏,您基本上都可以控制实例化过程,以及在您的具体情况中可能意味着什么。

【讨论】:

【参考方案2】:

__init__ 以已构建的对象实例作为第一个参数调用(通常称为 self,但这只是一个参数名称)。

__new__ 被称为传递 class 作为第一个参数,并期望返回一个实例(稍后将传递给 __init__)。

这允许例如__new__ 为不可变且身份不应该发挥作用的基于值的对象返回一个已经存在的实例。

【讨论】:

当你说__new__被称为传递作为第一个参数时,你指的是哪个类? @HelloGoodbye:正在构建的对象的类。这可以是您放置__new__ 的同一个类,也可以是从它派生的类(如果在此类之前列出的派生类或其他基类都没有定义__new__【参考方案3】:

考虑documentation on class customization了解更多详情。

根据这些方法的使用方式如下:__new__() 创建对象,__init__() 自定义对象。

正如 6502 所注意到的,__new__ 是静态方法的特例,获取类作为其参数,而__init__ 获取由__new__ 生成的对象

【讨论】:

以上是关于初始化器与构造器[重复]的主要内容,如果未能解决你的问题,请参考以下文章

对象初始化器与集合初初始化器

Python:迭代器与生成器

迭代器与生成器

迭代器与函数Python学习

为啥统一初始化没有显式构造函数[重复]

聚合初始化不支持构造函数访问[重复]