Why does Python seem to treat instance variables as shared between objects?
今天我正在编写一个简单的脚本,这时我注意到Python处理实例变量的方式有一个奇怪的怪癖。
假设我们有一个简单的对象:
1 2 3 4 5 6 7 8 | 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"] |
我们用单独的参数创建这个对象的两个实例:
1 2 3 4 5 | spam1 = Spam("Canadian bacon") spam2 = Spam("American bacon") print spam1 print spam2 |
结果令人费解:
1 2 | My favorite type of bacon is American bacon My favorite type of bacon is American bacon |
似乎所有不同的"垃圾邮件"实例都共享了"鸡蛋"字典——或者每次创建新实例时都会覆盖它。这不是日常生活中的问题,因为我们可以通过在初始化函数中声明实例变量来解决它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
用这种方式编写代码,结果就是我们期望的:
1 2 | My favorite type of bacon is Canadian bacon My favorite type of bacon is American bacon |
所以,虽然我没有被这种行为所阻碍,但我不理解为什么Python是这样工作的。有人能解释一下吗?
正如ignacio所发布的,在python的类范围内分配给的变量是类变量。基本上,在Python中,类只是
另一个注意事项:听起来你可能会从Java(或类似Java)的角度来看这个问题。也许你知道,因为Java需要显式声明变量,所以它需要在类作用域中有实例变量声明。
1 2 3 4 5 6 | class Foo { String bar; public Foo() { this.bar ="xyz"; } } |
注意,只有声明在类范围内。换句话说,为该变量分配的内存是类"template"的一部分,但变量的实际值不是。
python不需要任何变量声明。所以在python翻译中,只需删除声明。
1 2 3 4 | class Foo: # String bar; <-- useless declaration is useless def __init__(self): self.bar ="xyz" |
内存将在需要时被分配;只有分配是实际写出来的。这在构造器中,就像在Java中一样。
这不是实例变量,而是类变量。事实上,通过实例访问它是不相关的;它仍然是同一个对象。
与编译语言不同,python中的
当
在实际创建对象的实例并且运行
所以,当python解释器执行时
1 2 3 4 5 6 7 | class Spam(object): eggs = {} def __init__(self): <stuff> def __str__(self): <other stuff> |
它实际上是在运行时构建类对象。执行代码"
稍后,当它执行时
1 | spam1 = Spam() |
然后它创建一个新实例,并运行它的
实例本身作为