3

我看到以下 Python 文档说“在类中定义变量”将是类变量:

"程序员注:类定义中定义的变量是类变量;它们被所有实例共享。"

但是当我写这样的示例代码时:

class CustomizedMethods(object):
    class_var1 = 'foo'
    class_var2 = 'bar'

cm1 = CustomizedMethods()
cm2 = CustomizedMethods()
print cm1.class_var1, cm1.class_var2 #'foo bar'
print cm2.class_var1, cm2.class_var2 #'foo bar'
cm2.class_var1, cm2.class_var2 = 'bar','for'
print cm1.class_var1, cm1.class_var2 #'foo bar' #here not changed as my expectation
print cm2.class_var1, cm2.class_var2 #'bar foo' #here has changed but they seemed to become instance variables.

我很困惑,因为我尝试的与 Python 的官方文档不同。

4

5 回答 5

4

当您在实例上分配属性时,它会在实例上分配,即使它以前存在于类中。起初,class_var1确实class_var2是类属性。但是当你这样做时cm1.class_var1 = "bar",你并没有改变这个类属性。相反,您正在创建一个新属性,也称为class_var1,但这是 instance 上的一个实例属性cm1

这是另一个显示差异的示例,尽管仍然可能有点难以掌握:

>>> class A(object):
...     var = []
>>> a = A()
>>> a.var is A.var
True
>>> a.var = []
>>> a.var is A.var
False

起初,a.var is A.var是真的(即它们是同一个对象):因为a没有它自己的名为 的属性var,所以试图访问该类。在你给a它自己的实例属性之后,它就不再和类上的一样了。

于 2012-09-11T04:27:14.997 回答
1

您正在为实例分配属性,所以是的,它们此时成为实例变量。Python 在您指定的任何对象上查找属性,然后如果在其中找不到它们,则查找继承链(到类、类的父类等)。因此,您在实例上分配的属性“阴影”或“隐藏”类的同名属性。

于 2012-09-11T04:27:53.513 回答
0

当您重新分配cm2变量时,您创建了“隐藏”类变量的新实例变量。

>>> CustomizedMethods.class_var1 = 'one'
>>> CustomizedMethods.class_var2 = 'two'
>>> print cm1.class_var1, cm1.class_var2
one two
>>> print cm2.class_var1, cm2.class_var2
bar for
于 2012-09-11T04:26:43.980 回答
0

字符串是不可变的,因此类和实例变量之间的区别并不明显。对于类定义中的不可变变量,主要需要注意的是内存使用较少(即,如果您有 1,000 个 CustomizedMethods 实例,则仍然只有一个字符串“foo”的实例存储在内存中。)

但是,如果您不知道自己在做什么,在类中使用可变变量可能会引入细微的错误。

考虑:

class CustomizedMethods(object):
    class_var = {}

cm1 = CustomizedMethods()
cm2 = CustomizedMethods()

cm1.class_var['test'] = 'foo'
print cm2.class_var
  'foo'

cm2.class_var['test'] = 'bar'
print cm1.class_var
   'bar'
于 2012-09-11T04:27:03.140 回答
0

尝试

print cm1.__dict__ 
print cm2.__dict__ 

这将是启发...

当您向 cm2 询问一个属性时,它首先在实例的属性中查找(如果有一个与名称匹配),然后在类属性中查找是否没有匹配的属性。

所以 class_var1 和 class_var2 是类属性的名称。

还可以尝试以下方法:

cm2.__class__.class_var1 = "bar_foo" 
print cm1.class_var1 

你能指望什么?

于 2012-09-11T08:30:18.930 回答