6

Dictionaries and lists defined directly under the class definition act as static (e.g. this question)
How come other variables such as integer do not?

>>> 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}
Community
  • 1
  • 1
Jonathan Livni
  • 101,334
  • 104
  • 266
  • 359
  • check Omnifarious answer [here](http://stackoverflow.com/questions/8701500/python-class-instance-variables-and-class-variables/8701647#8701647) – joaquin Jan 03 '12 at 08:25
  • possible duplicate of http://stackoverflow.com/questions/68645/static-class-variables-in-python – gecco Jan 03 '12 at 08:37

3 Answers3

15

They are all class variables. Except for when you assigned a.bar=4 creating an instance variable. Basically Python has a lookup order on attributes. It goes:

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

So if you have

class Foo(object):
    bar = 1

This is a variable on the class Foo. Once you do

a = Foo()
a.bar = 2

you have created a new variable on the object a with the name bar. If you look at a.__class__.bar you will still see 1, but it is effectively hidden due to the order mentioned earlier.

The dict you created is at the class-level so it is shared between all instances of that class.

Michael Merickel
  • 23,153
  • 3
  • 54
  • 70
6

When you make the assignment

>>> a.bar=4

you are rebinding the Foo.bar name to 4, which is a new instance of an integer. On the other hand,

>>> a.bar[7]=8

Does not rebind Foo.bar to anything different, and simply modifies the dictionary that the name refers to.

If you do

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

then you will rebind Foo.bar to a new dictionary.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
1

Assuming a is an instance of A and A has a class attribute bar:

  • a.bar = 4 creates an instance attribute bar which hides the class bar in the context of a

  • a.bar[4] = 2 only modifies the object that the class-level bar binds to (assuming it supports indexing)

  • a.bar += 1 - This one is nasty. If the class-level bar supports the += operation (e.g. by implementing __iadd__()), then it is modified in-place and no object-level attribute is created. Otherwise it is equivalent to a.bar = a.bar + 1 and a new instance attribute bar is created.

Rafał Dowgird
  • 43,216
  • 11
  • 77
  • 90