Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does multiple inheritance work with the super() and different __init__() arguments?

I'm just diving into some more advanced python subjects (well, advanced to me at least). I am now reading about multiple inheritance and how you can use super(). I more or less understand the way the super function is used, but (1) What's wrong with just doing it like this?:

class First(object):     def __init__(self):         print "first"  class Second(object):     def __init__(self):         print "second"  class Third(First, Second):     def __init__(self):         First.__init__(self)         Second.__init__(self)         print "that's it" 

On to super(), Andrew Kuchlings paper on Python Warts says:

usage of super() will also be correct when the Derived class inherits from multiple base classes and some or all of them have init methods

So I rewrote the example above as follows:

class First(object):     def __init__(self):         print "first"  class Second(object):     def __init__(self):         print "second"  class Third(First, Second):     def __init__(self):         super(Third, self).__init__(self)         print "that's it" 

This however, only runs the first init it can find, which is in First. (2) Can super() be used to run both the init's from First and Second, and if so, how? Running super(Third, self).__init__(self) twice just runs First.init() twice..

To add some more confusion. What if the inherited classes' init() functions take different arguments. For example, what if I had something like this:

class First(object):     def __init__(self, x):         print "first"  class Second(object):     def __init__(self, y, z):         print "second"  class Third(First, Second):     def __init__(self, x, y, z):         First.__init__(self, x)         Second.__init__(self, y, z)         print "that's it" 

(3) How would I be able to supply the relevant arguments to the different inherited classes init functions using super()?

All tips are welcome!

ps. Since I have several questions I made them bold and numbered them..

like image 821
kramer65 Avatar asked May 31 '13 10:05

kramer65


People also ask

How does Super work with multiple inheritance Python?

Python super() function with multiple inheritance Python supports multiple inheritance, in which the derived class can inherit from multiple base classes that don't necessarily inherit from each other. In multiple inheritance, the features of all the parent classes are inherited into the child class.

What does super () __ init __ do?

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.

How does multiple inheritance work?

Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object or class may only inherit from one particular object or class.

How does super () method play an important role in inheritance?

In a class hierarchy with single inheritance, super helps to refer to the parent classes without naming them explicitly, thus making the code more maintainable. Here, with the help of super(). f1(), the f1() method of the super class of Child class i.e Parent class has been called without explicitly naming it.


2 Answers

For question 2, you need to call super in each class:

class First(object):     def __init__(self):         super(First, self).__init__()         print "first"  class Second(object):     def __init__(self):         super(Second, self).__init__()         print "second"  class Third(First, Second):     def __init__(self):         super(Third, self).__init__()         print "that's it" 

For question 3, that can't be done, your method needs to have the same signature. But you could just ignore some parameters in the parent clases or use keywords arguments.

like image 183
Guillaume Avatar answered Oct 11 '22 10:10

Guillaume


1) There is nothing wrong in doing like what u have done in 1, if u want to use the attributes from base class then u have to call the base class init() or even if u r using methods from base class that uses the attributes of its own class then u have to call baseclass init()

2) You cant use super to run both the init's from First and Second because python uses MRO (Method resolution order)

see the following code this is diamond hierarchy

class A(object):      def __init__(self):         self.a = 'a'         print self.a  class B(A):     def __init__(self):         self.b = 'b'         print self.b  class C(A):     def __init__(self):         self.c = 'c'         print self.c  class D(B,C):     def __init__(self):         self.d = 'd'         print self.d         super(D, self).__init__()  d = D() print D.mro() 

It prints:

d b [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 

MRO of python would be D,B,C,A

if B does't have init method it goes for C.

3) You can't do it all methods need to have same signature.

like image 45
Vb407 Avatar answered Oct 11 '22 10:10

Vb407