2

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.

2
  • Since c.counter is still 0, you obviously did not change its value. You did howver change the value of the counter attribute of the v instance. Commented Aug 2, 2010 at 15:27
  • You are looking for "static class variables", I think. Possibly a duplicate of stackoverflow.com/questions/68645/… Commented Aug 2, 2010 at 15:31

4 Answers 4

8

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]
>>> 
Sign up to request clarification or add additional context in comments.

1 Comment

I would word it: a new int object... to v.counter
0

Before:

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

During:

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

After:

c.counter = 0
v.counter = 1

Comments

0

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

Comments

0

Your are confused between declaration and instantiation.

C is the name of a class you declared.

v is an object, instantiated from c.

1 Comment

That's not the confusion here. If you set a variable on a class, you can read it just fine in exactly the manner above: instance.classvariable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.