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

classconstructormultiple-inheritancepythonsuper

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

Best Answer

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.