Vai*_*pai 40 python constructor initialization
潜入Python -
将它称为类的构造函数会很诱人但不正确.这很诱人,因为它看起来像构造函数(按照惯例,
__init__是为类定义的第一个方法),就像一个(它是在新创建的类实例中执行的第一段代码),甚至听起来像一个( "init"肯定表明了构造函数的本质.不正确,因为调用时已经构造了对象__init__,并且您已经拥有对该类的新实例的有效引用.
报价表明,它是不正确调用__init__的构造函数,因为该对象已建成的时候__init__被调用.但!我一直的印象是,在构造函数只调用构造对象之后,因为它本质上是使用,如果该对象未通过时存在来初始化实例,它是没有意义的数据成员的构造函数被调用?(来自C++/Java背景)
Ign*_*ams 35
如果你有一个班级,Foo那么:
Foo()是构造函数Foo.__init__()是初始化器Foo.__new__()是分配器构造Python对象只是分配一个新实例,然后初始化所述实例.
Ben*_*Ben 35
就个人而言,我发现" __init__不是一个构造函数"是非常精细的分裂.
__init__在请求新对象时调用.它应该使用其参数来为新对象分配属性,以便设置对象正常操作所需的不变量.该对象已经是一个有效的预先存在的位置,用于在代码__init__开始运行时存储属性.当代码__init__开始运行时(除了所有对象拥有的代码之外),新对象通常没有在其上定义任何属性.
在请求新对象时调用C++构造函数.它应该使用其参数来分配新对象上的字段,以便设置对象正常操作所需的不变量.在构造函数中的代码开始运行时,该对象已经是存储字段的有效预先存在的位置.当构造函数中的代码开始运行时,新对象已经具有所有已声明的字段,但它们包含垃圾.
在请求新对象时调用Java构造函数.它应该使用其参数来分配新对象上的字段,以便设置对象正常操作所需的不变量.在构造函数中的代码开始运行时,该对象已经是存储字段的有效预先存在的位置.当构造函数中的代码开始运行时,新对象已具有其所有声明的字段及其默认值.
__init__方法和C++/Java构造函数之间的主要区别在于我突出显示的最后一句话,这就是Java/C++的静态特性与Python的动态特性之间的区别.我不认为这保证称它们是根本不同的概念,不能用同一个词来指代.
我认为Pythonistas不喜欢将其__init__称为构造函数的主要原因是人们认为 C++/Java构造函数是"创建一个新对象",因为这就是他们在调用它们时所做的事情.但是当你调用一个构造函数时,真的会发生两件事; 创建一个新对象,然后调用构造函数初始化它.在C++/Java中,"创建新对象"的一部分是不可见的,而这可以在Python中公开/自定义(通过该__new__方法).
因此,尽管该__init__方法的作用与C++/Java构造函数的作用非常相似,但有些人更愿意通过说" __init__不是构造函数" 来强调这不是整个过程的事实.
小智 6
来自http://www.programiz.com/article/python-self-why
__init__()不是构造函数[..]一个重要的结论[..]是,
__init__()不是构造函数。许多天真的Python程序员对此感到困惑,因为__init__()当我们创建对象时它会被调用。仔细检查会发现,第一个参数__init__()是对象本身(对象已经存在)。该函数__init__()在对象创建后立即调用,并用于初始化它。从技术上讲,构造函数是创建对象本身的方法。在Python中,这个方法是
__new__(). 此方法的常见签名是
__new__(cls, *args, **kwargs)
关于本给出的答案,我在这里认为,大多数语言并不(完全)遵循该定义。
此外:
调用时
__new__(),类本身会自动作为第一个参数传递。这就是cls上面签名的用途。同样,像self,cls只是一个命名约定。此外,*args和**kwargs用于在 Python 中的方法调用期间获取任意数量的参数。实施时需要记住的一些重要事项
__new__()是:
__new__()总是在之前调用__init__()。- 第一个参数是隐式传递的类本身。
- 始终从 中返回一个有效的对象
__new__()。不是强制性的,但这就是重点。
底线(对我来说):__new__()似乎是构造函数,尽管__init__()通过所有实际手段__init__()做了大多数人认为构造函数会做的部分事情。
构造函数返回一个实例,并且可能失败。但是__init__不返回实例。即使在__init__引发异常时,__del__也称为删除实例。
可以在这里看到:
class A(object):
def __init__(self):
raise ValueError
def __del__(self):
print "Called"
def main():
try:
a = A()
except ValueError, e:
print "ValueError"
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
__new__ 另一方面,返回一个实例。