gpt4 book ai didi

python - 在 __init__ 之外初始化字段

转载 作者:太空宇宙 更新时间:2023-11-03 14:30:14 25 4
gpt4 key购买 nike

我需要一些帮助来理解 python 初始化的工作原理。我有一个类(Bar)和另一个类(Foo)作为字段/变量。当我尝试直接在 Bar 中(而不是在类 __init__ 中)初始化这个变量时,Bar 的所有实例都将指向同一个 Foo。但是如果我有一个 __init__ 方法,就像在 Bar2 中一样,每个 Bar2 实例都会有一个唯一的 Foo 实例。这里发生了什么?

class Foo():
number = 0

class Bar():
foo = Foo()

class Bar2():
foo = None

def __init__(self):
self.foo = Foo()

first = Bar()
second = Bar()

print "Bar"
print first
print second
print first.foo
print second.foo

first = Bar2()
second = Bar2()

print "\nBar2"
print first
print second
print first.foo
print second.foo

例如,输出将是:

Bar
<\__main__.Bar instance at 0x025B2AF8>
<\__main__.Bar instance at 0x025B2B20>
<\__main__.Foo instance at 0x004A3AA8>
<\__main__.Foo instance at 0x004A3AA8>

Bar2
<\__main__.Bar2 instance at 0x025B2B48>
<\__main__.Bar2 instance at 0x025B2AF8>
<\__main__.Foo instance at 0x025B2B70>
<\__main__.Foo instance at 0x025B2B98>

使用 Bar 两个实例将引用同一个 Foo 实例。为什么?

编辑:更正了为 Bar 打印两次 first.foo 的错误。产生的行为仍然如输出中所示。

最佳答案

Python 是一种动态语言。在像 Java 这样的静态语言中,编译器读取代码,找到类定义,判断它们是否正确并相应地生成一些代码。在 python 中,类定义(或函数定义)只是一个语句,就像对变量的赋值一样。语法略有不同。

定义类时,解释器运行类定义,即运行类行之后的所有代码。如果找到函数定义,它也会运行它们,即定义函数并将它们绑定(bind)到函数名称。由于类和函数定义与任何其他赋值一样都是语句,因此您也可以在很多地方使用它们。例如如下:

def foo():
class A: pass
a = A()
a.msg = "Hello"
return a

因为 python 是鸭子类型的(如果它叫起来像鸭子,看起来像一只鸭子,那么它就是一只鸭子),函数 foo 的用户甚至不必知道这个类叫什么,他们只需要知道 foo返回一个带有成员 msg 的对象。你会像这样使用它:

a = foo()
print a.msg

因此在您的示例中,当执行 Bar 的定义时,将运行类语句,包括创建 Foo 对象。当执行 Bar2 的定义时,类语句在其中运行,其中定义了一个名为 init 的函数。 Python 使用 this 作为要调用的函数的名称,当一个对象被创建时(在调用另一个函数 __new__ 之后,但这不是重点)。

因此,类定义(类内部的代码,Bar 创建 Foo 对象的代码)在引入类时仅运行一次。 __init__ 每次创建一个新对象时都会被一次又一次地调用,所以在 Bar2 中 Foo 的创建也是一次又一次地完成。

据我所知,“foo = None”是多余的,并不是真正需要的。在 python 中,您可以从任何地方添加实例变量,甚至可以从类外部添加实例变量,当然也可以从 __init__ 内部添加实例变量。

关于python - 在 __init__ 之外初始化字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12449107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com