This is detailed with a reasonable amount of detail by Guido himself in his blog post Method Resolution Order (including two earlier attempts).

In your example, Third() will call First.__init__. Python looks for each attribute in the class's parents as they are listed left to right. In this case, we are looking for __init__. So, if you define

class Third(First, Second):
    ...

Python will start by looking at First, and, if First doesn't have the attribute, then it will look at Second.

This situation becomes more complex when inheritance starts crossing paths (for example if First inherited from Second). Read the link above for more details, but, in a nutshell, Python will try to maintain the order in which each class appears on the inheritance list, starting with the child class itself.

So, for instance, if you had:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First):
    def __init__(self):
        print "third"

class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"

the MRO would be [Fourth, Second, Third, First].

By the way: if Python cannot find a coherent method resolution order, it'll raise an exception, instead of falling back to behavior which might surprise the user.

Example of an ambiguous MRO:

class First(object):
    def __init__(self):
        print "first"
        
class Second(First):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        print "third"

Should Third's MRO be [First, Second] or [Second, First]? There's no obvious expectation, and Python will raise an error:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution order (MRO) for bases Second, First

Why do the examples above lack super() calls? The point of the examples is to show how the MRO is constructed. They are not intended to print "first\nsecond\third" or whatever. You can – and should, of course, play around with the example, add super() calls, see what happens, and gain a deeper understanding of Python's inheritance model. But my goal here is to keep it simple and show how the MRO is built. And it is built as I explained:

>>> Fourth.__mro__
(<class '__main__.Fourth'>,
 <class '__main__.Second'>, <class '__main__.Third'>,
 <class '__main__.First'>,
 <type 'object'>)
Answer from rbp on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org › python › multiple-inheritance-in-python
Multiple Inheritance in Python - GeeksforGeeks
Class1 is the base, Class2 and Class3 inherit from it, Class4 inherits from both. Calling a method overridden in Class2 and Class3 creates ambiguity. Python uses MRO to resolve it and ensure a consistent call sequence. Python have a built-in solution to the Diamond Problem, and it's handled through the Method Resolution Order (MRO) using the C3 linearization algorithm. Method Resolution Order (MRO) in Python determines the order in which base classes are searched when looking for an attribute in multiple inheritance.
Published   December 27, 2025
Top answer
1 of 16
945

This is detailed with a reasonable amount of detail by Guido himself in his blog post Method Resolution Order (including two earlier attempts).

In your example, Third() will call First.__init__. Python looks for each attribute in the class's parents as they are listed left to right. In this case, we are looking for __init__. So, if you define

class Third(First, Second):
    ...

Python will start by looking at First, and, if First doesn't have the attribute, then it will look at Second.

This situation becomes more complex when inheritance starts crossing paths (for example if First inherited from Second). Read the link above for more details, but, in a nutshell, Python will try to maintain the order in which each class appears on the inheritance list, starting with the child class itself.

So, for instance, if you had:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First):
    def __init__(self):
        print "third"

class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"

the MRO would be [Fourth, Second, Third, First].

By the way: if Python cannot find a coherent method resolution order, it'll raise an exception, instead of falling back to behavior which might surprise the user.

Example of an ambiguous MRO:

class First(object):
    def __init__(self):
        print "first"
        
class Second(First):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        print "third"

Should Third's MRO be [First, Second] or [Second, First]? There's no obvious expectation, and Python will raise an error:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution order (MRO) for bases Second, First

Why do the examples above lack super() calls? The point of the examples is to show how the MRO is constructed. They are not intended to print "first\nsecond\third" or whatever. You can – and should, of course, play around with the example, add super() calls, see what happens, and gain a deeper understanding of Python's inheritance model. But my goal here is to keep it simple and show how the MRO is built. And it is built as I explained:

>>> Fourth.__mro__
(<class '__main__.Fourth'>,
 <class '__main__.Second'>, <class '__main__.Third'>,
 <class '__main__.First'>,
 <type 'object'>)
2 of 16
408

Your code, and the other answers, are all buggy. They are missing the super() calls in the first two classes that are required for co-operative subclassing to work. Better is:

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("third")

Output:

>>> Third()
second
first
third

The super() call finds the next method in the MRO at each step, which is why First and Second have to have it too, otherwise execution stops at the end of Second.__init__().


Without the super() calls in First and Second, the output is missing second:

>>> Third()
first
third
Discussions

A question about super() and multiple inheritance...
This is called "The Diamond Problem". As a rule we try to avoid it completely in python. If we use multiple inheritance it's usually with a mix-in, which would not share a master and generally does not even have an init method. But if you want to do it, you can do it one of 2 ways: manually with ClassName.__init__(self, args) or automagically with super().__init__(kwargs). Important: you cannot mix those two methods. The automagic relies on all of the calls using the super magic (aka the method resolution order, or mro, which you can see with ClassName.mro()). In your case you can do this: class A: def __init__(self, a): print(a) class B(A): def __init__(self, a, b): A.__init__(self, a) print(b) class C(A): def __init__(self, a, c): A.__init__(self, a) print(c) class D(B, C): def __init__(self, a, b, c, d): B.__init__(self, a, b) C.__init__(self, a, c) print(d) D('a', 'b', 'c', 'd') Or you can do this: class A: def __init__(self, a, **kwargs): print(a) class B(A): def __init__(self, b, **kwargs): super().__init__(**kwargs) print(b) class C(A): def __init__(self, c, **kwargs): super().__init__(**kwargs) print(c) class D(B, C): def __init__(self, d, **kwargs): super().__init__(**kwargs) print(d) D(a='a', b='b', c='c', d='d') (Note they are different both in how they are defined and in how they run.) More on reddit.com
🌐 r/learnpython
8
3
May 16, 2021
Multiple Inheritance weirdness
Working through this tutorial: Python Multiple Inheritance class Car: def __init__(self, door, wheel): self.door = door self.wheel = wheel def start(self): print('Start the Car') def go(self): print('Going') class Flyable: def __init__(self, wing): self.wing = wing def start(self): print('Start ... More on discuss.python.org
🌐 discuss.python.org
1
0
March 24, 2025
Multiple inheritance with ABC: which order?
I am making an abstract base class that inherits another ABC (collections.abc.Mapping). How is it better to order inheritance: 1) class MyClass(ABC, collections.abc.Mapping): ... OR 2) class MyClass(collections.abc.Mapping, ABC): ... i.e. inherit ABC first or last? More on discuss.python.org
🌐 discuss.python.org
1
0
May 29, 2025
Multiple Inheritance, super(), and different parameters
Here's what I think is "correct". I'm not an expert, but it follows the spirit of the MRO and produces working code. First, if your class isn't handling the argument, it should not explicitly accept it. In this case, AB shouldn't ask for foo or bar. The whole point of inheritance is that you can make changes to a base class without having to make changes to the extended classes. Instead, accept *args and **kwargs and pass them upstream: class AB(A,B): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) Second, if you use a class in an inheritance situation, you should be calling super().__init__(). "But, wait", you say, "you don't know if your class will be used in an inheritance situation". Correct, so you should basically always do this, IMO. class A: def __init__(self, foo, *args, **kwargs): super().__init__(*args, **kwargs) self.foo = foo class B: def __init__(self, bar, *args, **kwargs): super().__init__(*args, **kwargs) self.bar = bar Making the above changes causes your code to work perfectly, even if the parent classes change, or if you change the parent classes: >>> ab = AB(foo="f", bar="b") >>> ab <__main__.AB at 0x7fd614e4f280> >>> dir(ab) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo'] >>> ab.foo 'f' >>> ab.bar 'b' More on reddit.com
🌐 r/learnpython
7
1
September 3, 2020
🌐
Programiz
programiz.com › python-programming › multiple-inheritance
Python Multiple Inheritance (With Examples)
A class can be derived from more than one superclass in Python. This is called multiple inheritance.
🌐
Mimo
mimo.org › glossary › python › inheritance
Python Inheritance: Syntax, Usage, and Examples
Python supports multiple inheritance, which means a class can inherit from more than one parent.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python multiple inheritance
Python Multiple Inheritance
March 30, 2025 - Python multiple inheritance allows one class to inherit from multiple classes.
🌐
Codemistic
codemistic.github.io › python › multiple-inheritance-python.html
Multiple Inheritance in Python | Python Tutorials | CodeMistic
In multilevel inheritance,the features of base class is inherited to first derived class and then the second derived class which is inherited from first derived class will consist of features of first derived class and base class.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › a question about super() and multiple inheritance...
r/learnpython on Reddit: A question about super() and multiple inheritance...
May 16, 2021 -

If I run the following code I get an error.

class A:
    """
    This is the object which the other two objects
    will inherit from.
    """
    
    def __init__(self, a): print(a)

class B(A):
    """
    This is one of the parent objects.
    """

    def __init__(self, a, b): 
        super().__init__(a)
        print(b)

class C(A):
    """
    And the other one...
    """

    def __init__(self, a, c): 
        super().__init__(a)
        print(c)

class D(B, C):
    """
    And here's the problem:
    """

    def __init__(self, a, b, c, d):
        B.__init__(self, a, b)
        C.__init__(self, a, c)

        print(d)

D('a', 'b', 'c', 'd')

The problem with this code is that I have an object which inherits from two different objects that both use the super() method in their constructors. From the object D, I'm calling the constructors of the objects B and C. The problem is that I'm calling them using the parent classes' identifiers and passing the child object as the self argument. When the class B calls super().__init__, the interpreter understands that it's being called from the object D. The interpreter does its best and calls the constructor for C, but the constructor of B is calling the constructor of C via super() only with the parameter a, so a positional argument gets missing and I get this error:

Traceback (most recent call last):
  File ".../test.py", line 39, in <module>
    D('a', 'b', 'c', 'd')
  File ".../test.py", line 33, in __init__
    B.__init__(self, a, b)
  File ".../test.py", line 15, in __init__
    super().__init__(a)
TypeError: __init__() missing 1 required positional argument: 'c'

Does anyone know if I can choose which constructor to call using the super() function? Or if anyone has another better idea, I'd be thankful (because my code is quite a mess...).

Top answer
1 of 2
2
This is called "The Diamond Problem". As a rule we try to avoid it completely in python. If we use multiple inheritance it's usually with a mix-in, which would not share a master and generally does not even have an init method. But if you want to do it, you can do it one of 2 ways: manually with ClassName.__init__(self, args) or automagically with super().__init__(kwargs). Important: you cannot mix those two methods. The automagic relies on all of the calls using the super magic (aka the method resolution order, or mro, which you can see with ClassName.mro()). In your case you can do this: class A: def __init__(self, a): print(a) class B(A): def __init__(self, a, b): A.__init__(self, a) print(b) class C(A): def __init__(self, a, c): A.__init__(self, a) print(c) class D(B, C): def __init__(self, a, b, c, d): B.__init__(self, a, b) C.__init__(self, a, c) print(d) D('a', 'b', 'c', 'd') Or you can do this: class A: def __init__(self, a, **kwargs): print(a) class B(A): def __init__(self, b, **kwargs): super().__init__(**kwargs) print(b) class C(A): def __init__(self, c, **kwargs): super().__init__(**kwargs) print(c) class D(B, C): def __init__(self, d, **kwargs): super().__init__(**kwargs) print(d) D(a='a', b='b', c='c', d='d') (Note they are different both in how they are defined and in how they run.)
2 of 2
1
From the object D, I'm calling the constructors of the objects B and C. Don't do that. You cannot guarantee your direct ancestor, so you should only access the inheritance chain via super(). class A: """ This is the object which the other two objects will inherit from. """ def __init__(self, a): print(f"A.__init__ was passed a={a}") class B(A): """ This is one of the parent objects. """ def __init__(self, b, *args, **kwargs): super().__init__(*args, **kwargs) print(f"B.__init__ was passed b={b}") class C(A): """ And the other one... """ def __init__(self, c, *args, **kwargs): super().__init__(*args, **kwargs) print(f"C.__init__ was passed c={c}") class D(B, C): """ And here's the problem: """ def __init__(self, d, *args, **kwargs): super().__init__(*args, **kwargs) print(f"D.__init__ was passed d={d}") D("d", a="a", b="b", c="c")
🌐
Educative
educative.io › answers › what-is-multiple-inheritance-in-python
What is multiple inheritance in Python?
This is how we implement multiple inheritance using Base and derived classes. ... The classes Cars and Ids are superclass and Main is the subclass. The class Main extends both Cars and Ids to inherit the properties of both classes. The example is easy to understand if you have some knowledge of Python classes and Python inheritance.
🌐
Esri Community
community.esri.com › t5 › python-questions › how-does-multiple-inheritance-method-works-in › td-p › 1157273
Solved: How does multiple inheritance method works in? - Esri Community
March 25, 2022 - I am doing my college assignment and I got stuck here, I am not understanding the this function in multiple inheritances. # python 3 syntax # multiple inheritance example class parent1: # first parent class def func1: print(“Hello Parent1”) class parent2: # second parent class def func2: print(“Hello Parent2”) class parent3: # third parent class def func2: # the function name is same as parent2 print(“Hello Parent3”) class child(parent1, parent2, parent3): # child class def func3: # we include the parent classes print(“Hello Child”) # as an argument comma separated # Driver Code test = child() # object created test.func1() # parent1 method called via child test.func2() # parent2 method called via child instead of parent3 test.func3() # child method called # to find the order of classes visited by the child class, we use __mro__ on the child class print(child.__mro__)
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.3 documentation
A class definition with multiple base classes looks like this: class DerivedClassName(Base1, Base2, Base3): <statement-1> . . . <statement-N> For most purposes, in the simplest cases, you can think of the search for attributes inherited from a parent class as depth-first, left-to-right, not searching twice in the same class where there is an overlap in the hierarchy.
🌐
TechVidvan
techvidvan.com › tutorials › multiple-inheritance-in-python
Multiple Inheritance In Python with Examples - TechVidvan
August 22, 2024 - Learn multiple inheritance in python with examples. Understand the conflicts in multiple inheritance and how Method resolution order works.
🌐
AskPython
askpython.com › home › python multiple inheritance
Python Multiple Inheritance - AskPython
December 17, 2019 - When a class inherits from more than one class, it’s called multiple inheritances. Python supports multiple inheritances whereas Java doesn’t support it.
🌐
IBMMainframer
ibmmainframer.com › python-tutorial › multiple-inheritance
Multiple Inheritance
A class can be derived from more than one base class in Python, This is called multiple inheritance. In multiple inheritance, the features of all the base classes are inherited into the derived class.
🌐
Codemia
codemia.io › knowledge-hub › path › how_does_pythons_super_work_with_multiple_inheritance_1
How does Python's super work with multiple inheritance?
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
Python
pythonprogramminglanguage.com › multiple-inheritance
Multiple Inheritance - Python
In Python a class can inherit from more than one class. If a class inherits, it has the methods and variables from the parent classes. In essence, it’s called multiple inheritance because a class can inherit from multiple classes.
🌐
Quora
quora.com › Why-does-Python-support-multiple-inheritance-if-this-is-considered-a-bad-practice-and-most-languages-including-Java-dont
Why does Python support multiple inheritance if this is considered a bad practice and most languages, including Java, don't? - Quora
Answer (1 of 7): To reason behind this goes deep into what Python is about, the aims of the language. Python is built around a series of philosophies, as mentioned in, “The Zen of Python”. * Beautiful is better than ugly. * Explicit is better than implicit. * Simple is better than complex. *...
🌐
Reddit
reddit.com › r/learnpython › multiple inheritance, super(), and different parameters
r/learnpython on Reddit: Multiple Inheritance, super(), and different parameters
September 3, 2020 -

Hi,

I'm working on a class which needs to inherit from two different classes. I can find lots of articles online about multiple inheritance, however _none_ of them details what to do if the inherited classes both have different parameters. Take, for example:

class A:
    def __init__(self,foo):
        self.foo = foo
        
class B:
    def __init__(self,bar):
        self.bar = bar

class AB(A,B):
    def __init__(self,foo,bar):
        super().__init__(foo=foo,bar=bar)
        
AB("f","b")

This fails because super()._init__() only expected foo. How can I work super() work with multiple inheritance where the parameters are different??

Top answer
1 of 3
3
Here's what I think is "correct". I'm not an expert, but it follows the spirit of the MRO and produces working code. First, if your class isn't handling the argument, it should not explicitly accept it. In this case, AB shouldn't ask for foo or bar. The whole point of inheritance is that you can make changes to a base class without having to make changes to the extended classes. Instead, accept *args and **kwargs and pass them upstream: class AB(A,B): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) Second, if you use a class in an inheritance situation, you should be calling super().__init__(). "But, wait", you say, "you don't know if your class will be used in an inheritance situation". Correct, so you should basically always do this, IMO. class A: def __init__(self, foo, *args, **kwargs): super().__init__(*args, **kwargs) self.foo = foo class B: def __init__(self, bar, *args, **kwargs): super().__init__(*args, **kwargs) self.bar = bar Making the above changes causes your code to work perfectly, even if the parent classes change, or if you change the parent classes: >>> ab = AB(foo="f", bar="b") >>> ab <__main__.AB at 0x7fd614e4f280> >>> dir(ab) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo'] >>> ab.foo 'f' >>> ab.bar 'b'
2 of 3
2
Are you certain you need multiple inheritance? Can A or B be a member of AB?
🌐
Real Python
realpython.com › lessons › multiple-inheritance
Multiple Inheritance (Video) – Real Python
It manifests itself when you’re dealing with multiple inheritance, i.e., when your child class has more than one parent. In such a case, there could potentially be a conflict between identically named methods in your base classes.
Published   April 14, 2020