Python: understanding class and instance variables
I think I have some misconception about class and instance variables. Here is an example code:
class Animal(object): energy = 10 skills =  def work(self): print 'I do something' self.energy -= 1 def new_skill(self, skill): self.skills.append(skill) if __name__ == '__main__': a1 = Animal() a2 = Animal() a1.work() print a1.energy # result:9 print a2.energy # result:10 a1.new_skill('bark') a2.new_skill('sleep') print a1.skills # result:['bark', 'sleep'] print a2.skills # result:['bark', 'sleep']
I thought that
skill were class variables, because I declared them out of any method. I modify its values inside the methods in the same way (with
self in his declaration, maybe incorrect?). But the results show me that
energy takes different values for each object (like a instance variable), while
skills seems to be shared (like a class variable). I think I've missed something important...
You are running into initialization issues based around mutability.
First , the fix.
energy are class attributes. It is a good practice to consider them as read only, as initial values for instance attributes. The classic way to build your class is:
class Animal(object): energy = 10 skills =  def __init__(self,en=energy,sk=skills): self.energy=en self.skills=sk ....
Then each instance will have its own attributes, all your problems will disappear.
Second , what's happening with this code? Why is
skills shared, when
energy is per-instance?
-= operator is subtle. it is for in-place assignation if possible. The difference here is that
list types are mutable so in-place modification often occurs:
In : b= print(b,id(b)) b+=['strong'] print(b,id(b))  201781512 ['strong'] 201781512
a2.skills are the same list, which is also accessible as
energy is a non-mutable
int, so modification is impossible. In this case a new
int object is created, so each instance manages its own copy of the
In : a=10 print(a,id(a)) a-=1 print(a,id(a)) 10 1360251232 9 1360251200