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..
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.
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.
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.
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.
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.
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.
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