Python class variables or class variables in gener

2020-04-19 07:10发布

问题:

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 0xb64cb1dc>
>>> 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.

回答1:

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]
>>> 


回答2:

Before:

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

During:

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

After:

c.counter = 0
v.counter = 1


回答3:

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__.



回答4:

Your are confused between declaration and instantiation.

C is the name of a class you declared.

v is an object, instantiated from c.



标签: python oop