为什么有些类变量看起来像静态,而有些则不然?

时间:2012-01-03 08:18:29

标签: python

直接在类定义下定义的字典和列表充当静态(例如this question
为什么其他变量如整数不会?

>>> class Foo():
        bar=1

>>> a=Foo()
>>> b=Foo()
>>> a.bar=4
>>> b.bar
1
>>> class Foo():
        bar={}

>>> a=Foo()
>>> b=Foo()
>>> a.bar[7]=8
>>> b.bar
{7: 8}

3 个答案:

答案 0 :(得分:15)

它们都是类变量。除了您指定a.bar=4创建实例变量的时间。基本上Python有属性的查找顺序。它是:

instance -> class -> parent classes in MRO order (left to right)

所以,如果你有

class Foo(object):
    bar = 1

这是Foo类的变量。一旦你做了

a = Foo()
a.bar = 2

您已在对象a上创建了一个名为bar的新变量。如果您查看a.__class__.bar,您仍会看到1,但由于前面提到的顺序,它会被有效隐藏。

您创建的dict是在类级别,因此它在该类的所有实例之间共享。

答案 1 :(得分:6)

进行作业时

>>> a.bar=4

重新绑定 Foo.bar名称为4,这是一个整数的新实例。另一方面,

>>> a.bar[7]=8

不会将Foo.bar重新绑定到任何不同的地方,只需修改名称所引用的字典。

如果你这样做

>>> a.bar = {7: 8}

然后您将Foo.bar重新绑定到词典。

答案 2 :(得分:1)

假设aA的实例而A具有类属性bar

  • a.bar = 4创建一个实例属性bar,在bar

  • 的上下文中隐藏类a
  • a.bar[4] = 2仅修改类级bar绑定的对象(假设它支持索引)

  • a.bar += 1 - 这个讨厌。如果类级bar支持+=操作(例如,通过实现__iadd__()),则会就地修改它,并且不会创建任何对象级属性。否则,它等同于a.bar = a.bar + 1,并创建新的实例属性bar