这很诱人但不正确 称之为的构造函数 类。这很诱人,因为它看起来很棒 像一个构造函数(按照惯例,
__init__
是为类定义的第一个方法,就像一个人一样(它是 在a中执行的第一段代码 新创建的类实例), 甚至听起来像一个(“初始” 肯定建议一个构造函数 性质)。不正确,因为对象 已经建成了 时间__init__
被召唤,而你 已经有了有效的参考资料 该课程的新实例。
引用表明将__init__
作为构造函数调用是不正确的,因为该对象已在调用__init__
时构建。但!我一直认为只有在构造对象之后才调用构造函数,因为它主要用于初始化实例的数据成员,如果对象没有这样做则没有意义在构造函数被调用时存在? (来自C ++ / Java背景)
答案 0 :(得分:35)
答案 1 :(得分:31)
就我个人而言,我发现“__init__
不是构造函数”,可以很好地分解头发。
__init__
。它应该使用其参数来为新对象分配属性,以便设置对象正常操作所需的不变量。在__init__
中的代码开始运行时,该对象已经是存储属性的有效预先存在的位置。 当__init__
中的代码开始运行时,新对象通常没有定义任何属性(除了所有对象都拥有的代码)。
在请求新对象时调用C ++构造函数。它应该使用其参数来分配新对象上的字段,以便设置对象正常操作所需的不变量。在构造函数中的代码开始运行时,该对象已经是存储字段的有效预先存在的位置。 当构造函数中的代码开始运行时,新对象已经包含了所有已声明的字段,但它们包含垃圾。
请求新对象时调用Java构造函数。它应该使用其参数来分配新对象上的字段,以便设置对象正常操作所需的不变量。在构造函数中的代码开始运行时,该对象已经是存储字段的有效预先存在的位置。 当构造函数中的代码开始运行时,新对象已经具有所有声明的字段,并带有默认值。
__init__
方法和C ++ / Java构造函数之间的主要区别在于我突出显示的最后一句话,这就是Java / C ++的静态特性与Python的动态特性之间的区别。我认为这并不意味着要将它们称为根本不同的概念,而这些概念不应该被同一个词所引用。
我认为Pythonistas不喜欢将__init__
称为构造函数的主要原因是人们认为的C ++ / Java构造函数是“创建一个新对象”,因为那是当你打电话给他们时他们似乎做了什么。但是当你调用一个构造函数时,真的会发生两件事;创建一个新对象,然后调用构造函数初始化它。在C ++ / Java中,“创建新对象”的一部分是不可见的,而这可以在Python中公开/自定义(通过__new__
方法)。
因此虽然__init__
方法的角色与C ++ / Java构造函数的角色非常相似,但是有些人更喜欢强调这不是整个过程的事实,而是说{{1}不是构造函数“。
答案 2 :(得分:5)
构造函数返回实例,可能会失败。但__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()
另一方面, __new__
返回一个实例。
答案 3 :(得分:2)
来自http://www.programiz.com/article/python-self-why
__init__()
不是构造函数[..]一个重要的结论是[...],
__init__()
不是构造函数。许多天真的Python程序员都对它感到困惑,因为在创建对象时会调用__init__()
。仔细观察将发现__init__()
中的第一个参数是对象本身(对象已经存在)。函数__init__()
在创建对象后立即调用,并用于初始化它。从技术上讲,构造函数是一种创建对象本身的方法。在Python中,此方法为
__new__()
。这种方法的共同特征是
__new__(cls, *args, **kwargs)
关于Ben给出的回答,我会在这里争辩说,大多数语言都不会完全遵循这个定义。
此外:
调用
__new__()
时,类本身将自动作为第一个参数传递。这就是上述签名中cls
的用途。同样,与self
一样,cls
只是一个命名约定。此外,*args
和**kwargs
用于在Python中进行方法调用期间获取任意数量的参数。实施
__new__()
时要记住的一些重要事项是:始终在
__new__()
之前调用__init__()
。- 第一个参数是隐式传递的类本身。
- 始终从
醇>__new__()
返回有效对象。不是强制性的,但这就是重点。
Bottomline(对我而言):__new__()
似乎是构造函数,而不是__init__()
,尽管所有实际意义上__init__()
都是大多数人认为构造函数会做的事情的一部分。
答案 4 :(得分:0)
John Zelle撰写的“编程Python:计算机科学概论”中说,
“特殊方法__init__
是对象构造函数 .Python调用此方法初始化一个新对象。__init__
的作用是为实例变量提供初始值。对象“。
答案 5 :(得分:-6)
__init__
不是构造函数,但是由于您在学习Python时对您无关紧要的原因。它的行为方式与您习惯于在C ++和Java中运行的构造函数一样。