我今天正在编写一个简单的脚本,当时我注意到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"]
Run Code Online (Sandbox Code Playgroud)
我们使用单独的参数创建此对象的两个实例:
spam1 = Spam("Canadian bacon")
spam2 = Spam("American bacon")
print spam1
print spam2
Run Code Online (Sandbox Code Playgroud)
结果令人费解:
My favorite type of bacon is American bacon
My favorite type of bacon is American bacon
Run Code Online (Sandbox Code Playgroud)
似乎所有不同的"垃圾邮件"实例之间共享"蛋"字典 - 无论是每次创建新实例还是覆盖它.这在日常生活中并不是真正的问题,因为我们可以通过在初始化函数中声明实例变量来解决它:
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
Run Code Online (Sandbox Code Playgroud)
使用这种方式编写的代码,结果就是我们所期望的:
My favorite type of bacon is Canadian bacon
My favorite type of bacon is American bacon
Run Code Online (Sandbox Code Playgroud)
因此,虽然我并不担心这种行为,但我不明白为什么Python以这种方式工作.任何人都可以对此有所了解吗?
正如Ignacio发布的那样,在Python中分配给类范围的变量是类变量.基本上,在Python中,类只是语句下的class语句列表.一旦语句列表完成执行,Python就会挖掘在执行过程中创建的任何变量,并从中创建一个类.如果需要实例变量,实际上必须将其分配给实例.
另一方面:听起来你可能从Java(或类似Java)的角度来看这个问题.所以也许您知道因为Java要求显式声明变量,所以它需要在类范围内具有实例变量声明.
class Foo {
String bar;
public Foo() {
this.bar = "xyz";
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,只有声明在类范围内.换句话说,为该变量分配的内存是类"模板"的一部分,但变量的实际值不是.
Python不需要变量声明.所以在Python翻译中,你只需删除声明.
class Foo:
# String bar; <-- useless declaration is useless
def __init__(self):
self.bar = "xyz"
Run Code Online (Sandbox Code Playgroud)
内存将在需要时分配; 只有作业才被写出来.这就像构造函数一样,就像在Java中一样.
那不是实例变量,而是一个类变量.通过实例访问它的事实是无关紧要的; 它仍然是同一个对象.
| 归档时间: |
|
| 查看次数: |
1940 次 |
| 最近记录: |