混淆python类和实例变量

时间:2012-09-11 04:18:30

标签: python syntax

我看到以下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的官方文档。

5 个答案:

答案 0 :(得分:4)

在实例上分配属性时,它会在实例上分配,即使它以前存在于类中也是如此。起初,class_var1class_var2确实是类属性。但是当您执行cm1.class_var1 = "bar"时,您不会更改此类属性。相反,您正在创建一个新属性,也称为class_var1,但这个属性是实例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提供其自己的实例属性后,它将不再与该类的属性相同。

答案 1 :(得分:1)

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

答案 2 :(得分: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

答案 3 :(得分:0)

字符串是不可变的,因此类和实例变量之间的差异并不明显。对于类定义中的不可变变量,要注意的主要是减少对内存的使用(即,如果你有1000个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'

答案 4 :(得分:0)

尝试

print cm1.__dict__ 
print cm2.__dict__ 

它会很有启发......

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

因此class_var1和class_var2是类属性的名称。

还要尝试以下方法:

cm2.__class__.class_var1 = "bar_foo" 
print cm1.class_var1 
你期待什么?