开发者

Python class variables or class variables in general

From Dive into 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.

So I type this into IDLE:

IDLE 2.6.5      
>>> class c:
        counter=0


>>> c
<class __main__.c at 0xb64cb1dc>
>>> v=c()
>>> v.__class__
<class __main__.c at 0x开发者_Python百科b64cb1dc>
>>> v.counter += 1
>>> v.counter
1
>>> c.counter
0
>>> 

So what am I doing wrong? Why is the class variable not maintaining its value both through direct reference to the class and through any instance of the class.


Because ints are immutable in python

v.counter += 1

rebinds v.counter to a new int object. The rebinding creates an instance attribute that masks the class attribute

You can see this happening if you look at the id() of v.counter

>>> id(v.counter)
149265780
>>> v.counter+=1
>>> id(v.counter)
149265768

Here you can see that v now has a new attribute in its __dict__

>>> v=c()
>>> v.__dict__
{}
>>> v.counter+=1
>>> v.__dict__
{'counter': 1}

Contrast the case where counter is mutable, eg a list

>>> class c:
...  counter=[]
... 
>>> v=c()
>>> v.counter+=[1]
>>> c.counter
[1]
>>> 


Before:

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

During:

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

After:

c.counter = 0
v.counter = 1


Note that you can still get at the class value:

v.__class__.__dict__['counter'] 

will allow you to read or set to your class, even if you have obscured the symbol by adding a symbol to your instance's __dict__.


Your are confused between declaration and instantiation.

C is the name of a class you declared.

v is an object, instantiated from c.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜