__init__作为构造函数?

潜入Python –

这将是诱人的,但不正确的调用这个类的构造函数。 这很诱人,因为它看起来像一个构造函数(按照惯例, __init__是为类定义的第一个方法),就像一个(它是在新创build的类实例中执行的第一个代码片段),甚至听起来像一个(“init”当然暗示了构造函数的本质)。 不正确的,因为该对象已经被调用时__init__构造,并且您已经有一个有效的引用类的新实例。

引用build议调用__init__作为构造函数是不正确的,因为该对象已经在调用__init__的时候被构造了。 但! 我一直认为构造函数只有在构造对象之后才被调用,因为它基本上用于初始化实例的数据成员,如果对象在构造函数被调用时不存在? (来自C ++ / Java的背景)

如果你有一个Foo类,那么:

  • Foo()构造函数
  • Foo.__init__()初始化程序
  • Foo.__new__()分配器

Python对象的构build就是简单地分配一个新实例,然后初始化所述实例。

就我个人而言,我发现“ __init__不是一个构造函数”是非常好的分裂。

__init__在请求新对象时被调用。 它应该使用它的参数在新对象上分配属性,以便设置对象的正常操作所需的不variables。 该对象在__init__的代码开始运行时已经是一个有效的已存在属性。 __init__的代码开始运行时 (除了所有对象所拥有的代码除外) ,新对象通常没有定义它的属性

当一个新的对象被请求时,C ++构造函数被调用。 它应该使用它的参数来分配新对象上的字段,以便为对象的正常操作设置所需的不variables。 在构造函数中的代码开始运行时,该对象已经是一个有效的预存位置了。 当构造函数中的代码开始运行时,新对象已经有了所有声明的字段,但是它们包含垃圾。

当一个新的对象被请求时,Java构造函数被调用。 它应该使用它的参数来分配新对象上的字段,以便为对象的正常操作设置所需的不variables。 在构造函数中的代码开始运行时,该对象已经是一个有效的预存位置了。 当构造函数中的代码开始运行时,新对象具有所有已声明的字段,并具有其默认值。

__init__方法和C ++ / Java构造函数之间的主要区别在于我强调的最后一句话,这就是Java / C ++的静态本质和Python的dynamic本质之间的区别。 我不认为这是要求他们根本不同的概念,不能用同一个词来提及。

我认为Pythonistas不喜欢将__init__作为构造函数的主要原因是人们认为 C ++ / Java构造函数是“创build一个新对象”,因为这就是他们在调用它们时所要做的。 但是当你调用一个构造函数的时候真的有两件事情要做。 一个新的对象被创build,然后构造函数被调用来初始化它。 在C ++ / Java中,“创build新对象”部分是不可见的,而在Python中可以通过__new__方法进行公开/自定义。

所以尽pipe__init__方法的作用与C ++ / Java构造函数的作用非常相似,但有些人更喜欢强调这一事实,即并不是说“ __init__不是构造函数”。

构造函数返回一个实例,可能会失败。 但__init__不返回一个实例。 即使在__init__引发exception时,也会调用__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__返回一个实例。

John Zelle在“Programming Python:Introduction to Computer Science”中说:“ 特殊的方法__init__是对象的构造函数 ,Python调用这个方法来初始化一个新的对象, __init__的作用是为目的。”

http://www.programiz.com/article/python-self-why

__init__()不是一个构造函数

[..]一个重要的结论是, __init__()不是一个构造函数。 很多天真的Python程序员会因为__init__()在我们创build一个对象时被调用而感到困惑。 仔细检查会发现__init__()中的第一个参数是对象本身(对象已经存在)。 函数__init__()在创build对象后立即调用,并用于初始化它。

从技术上讲,构造函数是一种创build对象本身的方法。 在Python中,这个方法是__new__() 。 这种方法的共同特征是

__new__(cls, *args, **kwargs)

关于Ben给出的答案,我会在这里争辩说,大多数语言并不完全遵循这个定义。

此外:

__new__() ,类自身作为第一个参数自动传递。 这就是上面签名中的内容。 再一次,像self一样, cls只是一个命名约定。 此外, *args**kwargs用于在Python中进行方法调用时使用任意数量的参数。

在实现__new__()时要记住的一些重要的事情是:

  1. __init__()之前总是调用__new__() __init__()
  2. 第一个参数是隐式传递的类本身。
  3. 总是从__new__()返回一个有效的对象。 不是强制性的,但是这是整个问题。

底线(对我来说): __new__()似乎是构造函数,而不是__init__()虽然通过所有实际的方法__init__()是大多数人认为构造函数会做的一部分。

__init__不是一个构造函数,但是由于你学习Python对于你来说并不重要。 它的行为方式就像习惯了C ++和Java中的构造函数一样。