gpt4 book ai didi

python - 为什么 Python 似乎将实例变量视为在对象之间共享?

转载 作者:太空狗 更新时间:2023-10-29 22:07:08 26 4
gpt4 key购买 nike

今天我正在编写一个简单的脚本,这时我注意到 Python 处理实例变量的方式有一个奇怪的怪癖。

假设我们有一个简单的对象:

class Spam(object):
eggs = {}

def __init__(self, bacon_type):
self.eggs["bacon"] = bacon_type

def __str__(self):
return "My favorite type of bacon is " + self.eggs["bacon"]

然后我们用不同的参数创建这个对象的两个实例:

spam1 = Spam("Canadian bacon")
spam2 = Spam("American bacon")

print spam1
print spam2

结果令人费解:

My favorite type of bacon is American bacon
My favorite type of bacon is American bacon

似乎“eggs”字典在所有不同的“垃圾邮件”实例之间共享——或者每次创建新实例时它都会被覆盖。这在日常生活中并不是一个真正的问题,因为我们可以通过在初始化函数中声明实例变量来解决它:

class Spam(object):

def __init__(self, bacon_type):
self.eggs = {}
self.eggs["bacon"] = bacon_type

def __str__(self):
return "My favorite type of bacon is " + self.eggs["bacon"]

spam1 = Spam("Canadian bacon")
spam2 = Spam("American bacon")

print spam1
print spam2

这样写的代码,结果就是我们所期望的:

My favorite type of bacon is Canadian bacon
My favorite type of bacon is American bacon

因此,虽然我不为这种行为所困扰,但我不明白为什么 Python 会这样工作。任何人都可以阐明这一点吗?

最佳答案

正如 Ignacio 发布的那样,在 Python 中分配给类范围的变量是类变量。基本上,在 Python 中,类只是 class 语句下的语句列表。一旦该语句列表执行完毕,Python 就会收集在该执行过程中创建的所有变量,并从中创建一个类。如果你想要一个实例变量,你实际上必须将它分配给实例。

另一方面:听起来您可能是从 Java(或类似 Java)的角度来看这个问题的。所以您可能知道,因为 Java 需要显式声明变量,所以它需要在类范围内声明实例变量。

class Foo {
String bar;
public Foo() {
this.bar = "xyz";
}
}

请注意,只有声明 在类范围内。换句话说,为该变量分配的内存 是类"template"的一部分,但变量的实际 不是。

Python 不需要任何变量声明。所以在 Python 翻译中,您只需删除声明。

class Foo:
# String bar; <-- useless declaration is useless
def __init__(self):
self.bar = "xyz"

内存会在需要的时候分配;实际上只有作业被写出来。这在构造函数中进行,就像在 Java 中一样。

关于python - 为什么 Python 似乎将实例变量视为在对象之间共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8860447/

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