Reputation: 111
I am confused with variable sharing concept in Python in inheritance.
Consider the following code:-
class a(object):
var1 = 0
var2 = {}
def print_var(self):
print(self.var1)
print(self.var2)
class b(a):
@classmethod
def modify_var(cls):
cls.var1 = 1
cls.var2['temp']="something"
o1 = a()
o2 = b()
print("Initial Values")
o1.print_var()
o2.print_var()
print("Changing Values")
o2.modify_var()
print("Print values after change")
o1.print_var()
o2.print_var()
After running above code I can see the dictionary is being shared between child and parent class, but integer variable isn't.
Can anyone please explain this, or what I am doing wrong here?
Output of above code:
Initial Values
0
{}
0
{}
Changing Values
Print values after change
0 # <- this zero should be one according to my understanding
{'temp': 'something'}
1
{'temp': 'something'}
Upvotes: 6
Views: 3129
Reputation: 36598
In general, you do not want to use mutable class variables. A class variable is shared by object reference to all instances of the class. But it is not shared across inherited classes.
So all instances of a
share object references to a.var1
and a.var2
. Similarly, all instances of b
share object references to b.var1
and b.var2
. Upon creating the inheritance, b
also get the references to var1
and var2
, but they are not shared back to a
or any instantiations of a
.
Because you use a mutable object for var2
, the object's reference is never changed after the inheritance. So you can modify var2
and it will be modified for all references to it, because the object reference is the same.
If you reassign var2
instead of modifying it, you get the expected behavior.
Try this:
class a(object):
var1 = 0
var2 = {}
def print_var(self):
print(self.var1, end=', ')
print(self.var2)
class b(a):
@classmethod
def modify_var(cls):
cls.var1 = 1
cls.var2 = {'temp': 'something'} # reassign to a new dict
Here are some tests:
ob1 = a()
ob2 = b()
o1.print_var()
o2.print_var()
o2.modify_var()
o1.print_var()
o2.print_var()
# prints
0, {}
0, {}
0, {}
1, {'temp': 'something'}
Upvotes: 5