Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why some class variables seem to act as static while others don't?

Tags:

python

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}
like image 326
Jonathan Livni Avatar asked Jan 03 '12 08:01

Jonathan Livni


People also ask

Why do we need to declare a variable as static?

A variable is declared as static to get the latest and single copy of its value; it means the value is going to be changed somewhere.

When should variables be static?

Static variables are used to keep track of information that relates logically to an entire class, as opposed to information that varies from instance to instance.

Why doesn't Python have static types?

Someone may eventually come up with a statically typed version of Python but it's highly unlikely it will catch on. The reason Python is so popular is because it is extremely easy to learn and very flexible for programming. Static typing would compromise these qualities.


2 Answers

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.

like image 131
Michael Merickel Avatar answered Sep 20 '22 16:09

Michael Merickel


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.

like image 20
Greg Hewgill Avatar answered Sep 22 '22 16:09

Greg Hewgill