Method Resolution Order (MRO) in Python

  Add to Bookmark

Introduction

In Python, Method Resolution Order (MRO) determines the sequence in which base classes are searched when calling a method on an object. This is especially important in multiple inheritance, where a class inherits from multiple parent classes.

In this tutorial, we will cover:

  1. What is MRO?
  2. How MRO works in Python?
  3. The C3 Linearization (C3 MRO Algorithm)
  4. The super() function and MRO
  5. Practical examples and edge cases

1. What is Method Resolution Order (MRO)?

MRO defines the order in which Python looks for methods when a method is called on an object. It ensures:
Consistency in method calls
Avoids redundant calls in multiple inheritance
Prevents infinite loops

Example

class A:
    def show(self):
        print("A")

class B(A):
    pass

class C(A):
    def show(self):
        print("C")

class D(B, C):  # Multiple Inheritance
    pass

d = D()
d.show()  # Output: C

Python looks for show() in D → B → C → A (Left to Right).
The first occurrence of show() is in C, so C.show() is executed.

Check MRO using __mro__ or mro()

print(D.__mro__)  
# Output: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

2. How MRO Works in Python?

MRO follows a depth-first, left-to-right approach, but it ensures that:

  1. A child class is checked before its parents.
  2. If a class appears multiple times, it is checked only once (leftmost occurrence).
  3. The object class is always at the end.

Example

class X:
    def show(self):
        print("X")

class Y(X):
    def show(self):
        print("Y")

class Z(X):
    pass

class M(Y, Z):
    pass

m = M()
m.show()  # Output: Y

MRO: M → Y → Z → X → object
show() is found in Y, so Y.show() is executed.

Check MRO:

print(M.mro())  
# Output: [<class '__main__.M'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.X'>, <class 'object'>]

3. C3 Linearization (C3 MRO Algorithm)

Python uses the C3 Linearization algorithm (or C3 MRO) to determine MRO in multiple inheritance.

C3 MRO ensures:

  1. Preserved Inheritance Order – The order in which base classes are listed is followed.
  2. Single Occurrence Rule – A class appears only once in MRO.
  3. Parent Before Child – Parent classes appear before their children.

Example of C3 MRO

class A:
    pass

class B(A):
    pass

class C(A):
    pass

class D(B, C):  
    pass

print(D.mro())  
# Output: [D, B, C, A, object]

How C3 Works?

  • Start with D → Look at B and C → Then A → Finally, object.
  • The leftmost base (B) is checked before C.
  • A appears only once, ensuring consistency.

4. The super() Function and MRO

The super() function follows MRO to determine which method to call.

 Example: Using super() in multiple inheritance

class A:
    def show(self):
        print("A")

class B(A):
    def show(self):
        print("B")
        super().show()

class C(A):
    def show(self):
        print("C")
        super().show()

class D(B, C):
    def show(self):
        print("D")
        super().show()

d = D()
d.show()

Output:

D
B
C
A

D.show() is executed first.
super().show() in D calls B.show().
super().show() in B calls C.show().
super().show() in C calls A.show().
A.show() does not call super(), so execution stops.


5. Practical Examples and Edge Cases

Diamond Problem in Multiple Inheritance

The diamond problem occurs when a class inherits from two classes that have a common parent.

class A:
    def show(self):
        print("A")

class B(A):
    def show(self):
        print("B")

class C(A):
    def show(self):
        print("C")

class D(B, C):  # Diamond inheritance
    pass

d = D()
d.show()  # Output: B

MRO: D → B → C → A → object

  • D checks B first, so B.show() is executed.
  • A is visited only once (C3 MRO ensures this).

6. Summary

MRO determines the order in which methods are called in multiple inheritance
Python follows C3 Linearization (C3 MRO algorithm)
Use __mro__ or mro() to check MRO
super() follows MRO and avoids redundant calls
MRO prevents the Diamond Problem by ensuring a single occurrence of each class