Regarding multiple parent inheritance, when I call the super
.__init__
, why doesn't parent2's __init__
function get called? Thanks.
class parent(object): var1=1 var2=2 def __init__(self,x=1,y=2): self.var1=x self.var2=y class parent2(object): var4=11 var5=12 def __init__(self,x=3,y=4): self.var4=x self.var5=y def parprint(self): print self.var4 print self.var5 class child(parent, parent2): var3=5 def __init__(self,x,y): super(child, self).__init__(x,y) childobject = child(9,10) print childobject.var1 print childobject.var2 print childobject.var3 childobject.parprint()
Output is
9 10 5 11 12
Inheritance is the mechanism to achieve the re-usability of code as one class(child class) can derive the properties of another class(parent class). It also provides transitivity ie. if class C inherits from P then all the sub-classes of C would also inherit from P.
A class can be derived from more than one base class in Python, similar to C++. This is called multiple inheritance. In multiple inheritance, the features of all the base classes are inherited into the derived class.
When you initialize a child class in Python, you can call the super(). __init__() method. This initializes the parent class object into the child class. In addition to this, you can add child-specific information to the child object as well.
The Problem with Multiple Inheritance If you allow multiple inheritance then you have to face the fact that you might inherit the same class more than once. In Python as all classes inherit from object, potentially multiple copies of object are inherited whenever multiple inheritance is used.
If you want to use super
in child
to call parent.__init__
and parent2._init__
, then both parent __init__
s must also call super
:
class parent(Base): def __init__(self,x=1,y=2): super(parent,self).__init__(x,y) class parent2(Base): def __init__(self,x=3,y=4): super(parent2,self).__init__(x,y)
See "Python super method and calling alternatives" for more details on the sequence of calls to __init__
caused by using super
.
class Base(object): def __init__(self,*args): pass class parent(Base): var1=1 var2=2 def __init__(self,x=1,y=2): super(parent,self).__init__(x,y) self.var1=x self.var2=y class parent2(Base): var4=11 var5=12 def __init__(self,x=3,y=4): super(parent2,self).__init__(x,y) self.var4=x self.var5=y def parprint(self): print self.var4 print self.var5 class child(parent, parent2): var3=5 def __init__(self,x,y): super(child, self).__init__(x,y) childobject = child(9,10) print childobject.var1 print childobject.var2 print childobject.var3 childobject.parprint()
You might be wondering, "Why use Base
?". If parent
and parent2
had inherited directly from object
, then super(parent2,self).__init__(x,y)
would call object.__init__(x,y)
. That raises a TypeError
since object.__init__()
takes no parameters.
To workaround this issue, you can make a class Base
which accepts arguments to __init__
but does not pass them on to object.__init__
. With parent
and parent2
inheriting from Base
, you avoid the TypeError
.
Because parent
is next in method resolution order (MRO), and it never uses super()
to call into parent2
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With