关于oop:python类变量或类变量

Python class variables or class variables in general

从潜入Python:

Class attributes are available both through direct reference to the
class and through any instance of the class.

Class attributes can be used as class-level constants, but they are
not really constants. You can also change them.

所以我把它输入idle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IDLE 2.6.5      
>>> class c:
        counter=0


>>> c
<class __main__.c at 0xb64cb1dc>
>>> v=c()
>>> v.__class__
<class __main__.c at 0xb64cb1dc>
>>> v.counter += 1
>>> v.counter
1
>>> c.counter
0
>>>

我做错了什么?为什么类变量不通过直接引用类和通过类的任何实例来维护其值?


因为ints在python中是不可变的

1
v.counter += 1

v.counter重新绑定到新的int对象。重新绑定将创建一个实例属性,该属性将屏蔽类属性

如果你看一下v.counterid(),你就会看到这种情况的发生。

1
2
3
4
5
>>> id(v.counter)
149265780
>>> v.counter+=1
>>> id(v.counter)
149265768

在这里,您可以看到v在其__dict__中有一个新的属性。

1
2
3
4
5
6
>>> v=c()
>>> v.__dict__
{}
>>> v.counter+=1
>>> v.__dict__
{'counter': 1}

counter是可变的情况相比,例如list是可变的。

1
2
3
4
5
6
7
8
>>> class c:
...  counter=[]
...
>>> v=c()
>>> v.counter+=[1]
>>> c.counter
[1]
>>>


请注意,您仍然可以获取类值:

1
v.__class__.__dict__['counter']

将允许您读取或设置类,即使您通过向实例的_uuu dict_uuuuuuuu添加符号来隐藏符号。


之前:

1
2
c.counter = 0
v.counter -> c.counter

期间:

1
2
c.counter = 0
v.counter = c.counter + 1

后:

1
2
c.counter = 0
v.counter = 1

您将混淆声明和实例化。

C是您声明的类的名称。

V是一个对象,由C实例化。