Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding instance and class variable python

Tags:

python

Let's suppose I have 2 classes in different scenario.

Scenario 1

class MyClass():
    temp = 5

Scenario 2

class MyClass():
    temp = 5

    def myfunc(self):
          print self.temp

Now when will variable temp will be treated as a class variable and instance variable. I am confused because in both the scenarios I am able to access the value of variable temp using both.

  1. Object.Temp (behaving as instance variable)

  2. ClassName.Temp (behaving as class variable)

I believe similar questions have been asked before but it will be a great help if someone can explain this in context of my question.

like image 684
RanRag Avatar asked Jun 02 '12 12:06

RanRag


2 Answers

Class variables are shared between all instances of a class. With immutable types (like int, str, ...) you won't note much of a difference. But consider this:

class MyClass():
    temp = []  
    def myfunc(self, val):
          self.temp.append(val)
          print self.temp

instance1 = MyClass()
instance1.myfunc(1)    # [1]
instance2 = MyClass()
instance2.myfunc(2)    # [1, 2]

In this case both instances share the same list, that is if the instance doesn't have a temp member itself, then that of the class is used.

So if you further do:

MyClass.temp.append(3)
print instance1.temp   # [1, 2, 3]
instance1.temp = []
print instance1.temp   # []         uses the instances temp
print instance2.temp   # [1, 2, 3]
del instance1.temp
print instance1.temp   # [1, 2, 3]  uses the class' temp again
like image 76
mata Avatar answered Oct 13 '22 03:10

mata


Basically, MyClass.temp is always a class variable. Getting obj.temp returns the class variable, until you try to set obj.temp, which creates a member variable that masks the class variable. I hope this helps:

>>> class MyClass(object):
...     temp = 5
... 
>>> a = MyClass()
>>> b = MyClass()
>>> a.temp
5
>>> b.temp
5
>>> b.temp = 6
>>> a.temp
5
>>> MyClass.temp = 7
>>> a.temp
7
>>> b.temp
6
>>> a.__dict__
{}
>>> b.__dict__
{'temp': 6}
>>> MyClass.__dict__
{..., 'temp': 7}

Edit: As mata says, calling methods (such as append()) on obj.temp does not count as "setting" it.

like image 25
robert Avatar answered Oct 13 '22 01:10

robert