In a Python multiple inheritance situation, why do the root classes need to call super().__init__()?

Why is the presence of super().__init__() in the base classes necessary for the super().__init__() in the child class to run through both inheritance branches?

The code below illustrates what happens with and without super().__init__() in the base classes:

import sys
#--------------------------------
class one():
  def __init__(self):
    super().__init__()
    print("one")


class two():
  def __init__(self):
    super().__init__()
    print("two")

class three(one,two):
  def __init__(self):
    super().__init__()
    print("three") 
#--------------------------------

class uno():
  def __init__(self):
    print("uno")

class dos():
  def __init__(self):
    print("dos")

class tres(uno,dos):
  def __init__(self):
    super().__init__()
    print("tres") 
    
print("python version")
print(sys.version)
print("---------------")
a = three()
print("---------------")
b = tres()

Output:

python version
3.8.12 (default, Aug 30 2021, 16:42:10) 
[GCC 10.3.0]
---------------
two
one
three
---------------
uno
tres

2 answers

  • answered 2022-05-04 17:03 Frank Yellin

    super() is misnamed in the multiple-inheritance case. Every class has a list of classes called the "method resolution order". For single inheritance, it is precisely each class followed by its superclass. For multiple inheritance, it is more complicated.

    super() says to call the next implementation in the object's method resolution order. For this class, the mro is tres, then uno, then dos, then object.

    Google "Method resolution order" for more info.

  • answered 2022-05-04 17:10 Mohamed Yasser

    Usually in multiple inheritance, if the two parent classes have the same definition (in this case __init__), the child calls the first parent (in this case its one). However, inside one's __init__ you call another super, but you will notice that one has no parent. In this case python calls the second parent's __init__.

    Try removing the super from inside two. You will have the same output. Now undo the deleted super, delete the super from class one, and change the order of inheritance:

    class three(two,one):
    

    You will have three calling two which then calls one; therefore outputting "one two three". Multiple inheritance and multi-level inheritance have some special cases like that, and I agree with Frank Yellin that it is better for you to just read about MRO.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum