Python 创建实例时对uuu init_uuuu的默认调用
只是想得到一些帮助来理解这些代码行:Python 创建实例时对uuu init_uuuu的默认调用,python,oop,instance,Python,Oop,Instance,只是想得到一些帮助来理解这些代码行: class Parent: def __init__(self): print("instance created") parent1=Parent() parent2=Parent.__init__(parent1) 输出 instance created instance created 我试图理解python的OOP中如何调用构造函数 在第一行中,默认情况下调用方法\uuuuu init\uuuu,传递的自参数是paren
class Parent:
def __init__(self):
print("instance created")
parent1=Parent()
parent2=Parent.__init__(parent1)
输出
instance created
instance created
我试图理解python的OOP中如何调用构造函数
在第一行中,默认情况下调用方法\uuuuu init\uuuu
,传递的自参数是parent1
第二行是我认为调用方法的更传统的方式。因为
\uuuu init\uuuu
将父类的一个实例作为一个参数,所以我传递了父类1
,它可以工作。我知道第二行发生了什么,只是想问一下计算机在第一行创建实例parent1
时做了什么。\uuuu init\uu
相当于Python中的构造函数。将面向对象语言视为一种对表示对象方法的函数具有强制参数的语言,因此您始终可以访问该函数中的对象。大多数语言都不会让你以输入this
的方式输入。Python使用self
,并让您为每个方法键入它。这是一样的,只是没有为你做额外的工作
因此,当Python实例化一个类时,它会将该类传递给该类的\uuuu new\uuu
函数,生成一个对象,然后将该对象作为第一个参数传递给该类的\uuu init\uuu
函数 \uuuu init\uuuuu
不是构造函数,而是初始值设定项。当Python创建一个对象时,它实际上是在\uuuu new\uuuuu
中创建的(通常作为默认值,它只生成右类的一个空对象),该对象接收对该类的引用,并返回一个实例(通常为空;未设置属性)。生成的实例在\uuuu init\uuuu
中作为self
隐式传递,然后建立实例属性
通常,您不会直接调用像\uuu init\uuu
这样的特殊方法(除了涉及到带有协作继承的super()
的情况之外),您只需要让Python为您做。避免调用\uuuuuu init\uuuuuu
的唯一方法是显式调用类的\uuuu new\uuuuuuu
(这也是非常不寻常的)。您是正确的,\uuuuu init\uuuuuuuuuuuu()
像构造函数一样工作,在实例化对象时会自动运行(如果有帮助的话,Java构造函数也会这样)。尽管您可以调用\uuuuuu init\uuuuu
,但您不应该调用以\uuu
或\uuuuu
开头的函数/方法,它们是从类/对象调用的
当self
在类方法中作为参数出现时,您不必提供对象的名称,Python会找到它。因此,不建议使用上面的第二行(Parent2=…
)。请参阅文档:
在创建实例之后(通过\uuuu new\uuuu()
)调用,但在实例返回给调用方之前调用。参数是传递给类构造函数表达式的参数
调用以创建类cls的新实例\uuuu new\uuuuu()
是一个静态方法(有特殊的大小写,因此您不需要声明它),它将请求实例的类作为其第一个参数。其余参数是传递给对象构造函数表达式的参数
因此,在parent1=Parent()
中,Python基本上是这样做的:
_temp_new_parent = Parent.__new__(Parent) # Inherited from "object.__new__"
Parent.__init__(_temp_new_parent)
parent1 = _temp_new_parent
(\u temp\u new\u parent
实际上并不存在,我只是将其作为一种抽象使用。)
请注意,\uuu init\uuu()
不会返回任何内容,因此在代码中,parent2是None
。如果\uuuu init\uuuu()
设置了实例属性,它会将它们设置在parent1
上,因为这是您传入的内容。在第一行中,最好说self
的值是最终将分配给parent1
的对象。说它是parent1
是不对的,因为变量还不存在!这就是\uuuuu new\uuuuu
创建的对象,对吗?我这样做主要是为了测试我的理解,因为我第一次看到这种情况是在查看继承时(如您所述)。我可以问一下构造函数和初始化器之间的确切区别是什么吗?请仔细阅读-\uuuuu new\uuuuu
构造正确类的对象,因此这里是构造函数吗?然而,\uuuuu innit\uuuu
只是获取创建的实例并建立指定的任何属性,所以称为初始化器?这是一个仅在python中存在的区别<代码>\uuuu new\uuuu
接收一个类和传入的参数,并返回一个对象。它是构造函数<代码>\uuuu init\uuuu接收一个对象,并期望根据参数对其进行变异。大多数其他OO语言都有一个“构造函数”,它的功能更像“初始值设定项”@V.Jain:明白了。Python可以在\uuuuuu new\uuuuu
中进行构造和初始化(这是编写不可变类的推荐方法,因为它可以防止多次调用\uuuuuuu init\uuuuuu
,并以意外的方式修改实例),但从历史上看,\uuuuuuuuuuuu new\uuuu
甚至不存在<代码>\uuuu init\uuuuu是所有的一切,而内置的对象构造机械只负责创建(空)实例本身<代码>\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu保存了\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。例如,Java的“构造函数”实际上是初始值设定项,因为可以获取对内存中存在的对象(即已构造)的引用,但其所谓的“构造函数”尚未执行