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

kramer65 picture kramer65 · May 31, 2013 · Viewed 10.8k times · Source

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

Answer

Guillaume picture Guillaume · May 31, 2013

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.