关于python:为什么有些类变量似乎是静态而其他类不是?

Why some class variables seem to act as static while others don't?

直接在类定义下定义的字典和列表是静态的(例如,这个问题)其他变量,比如整数,为什么不呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> 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}


它们都是类变量。除了在指定a.bar=4创建实例变量时。基本上,python在属性上有一个查找顺序。它是这样的:

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

如果你有

1
2
class Foo(object):
    bar = 1

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

1
2
a = Foo()
a.bar = 2

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

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


当你完成任务时

1
>>> a.bar=4

您正在将Foo.bar名称重新绑定到4,这是整数的新实例。另一方面,

1
>>> a.bar[7]=8

不会将cx1〔0〕重新绑定到任何不同的地方,只需修改名称所引用的字典。

如果你这样做了

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

然后您将重新绑定到新字典中。


假设aa的实例,a具有类属性bar

  • a.bar = 4创建了一个实例属性bar,它在a的上下文中隐藏了类bar

  • a.bar[4] = 2只修改类级bar绑定到的对象(假设它支持索引)

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