Site Tools


python-mro

Table of Contents

Python MRO

Python MRO (Method Resolution Order) defines the order in which Python looks for a method or attribute in a class hierarchy. With multiple inheritance, determining which parent class's method to call requires a consistent, predictable algorithm—Python uses C3 linearization.

Understanding MRO is essential for debugging multiple inheritance and knowing which method actually runs.

Example

This example shows MRO with multiple inheritance and how methods are resolved.

# run: python3 mro.py
# description: method resolution order in multiple inheritance
 
class A:
    def method(self):
        print("A.method")
 
    def a_only(self):
        print("A.a_only")
 
class B(A):
    def method(self):
        print("B.method")
 
    def b_only(self):
        print("B.b_only")
 
class C(A):
    def method(self):
        print("C.method")
 
    def c_only(self):
        print("C.c_only")
 
class D(B, C):
    pass
 
# Show MRO
print("MRO for D:")
for i, cls in enumerate(D.__mro__):
    print(f"  {i}: {cls.__name__}")
 
# Method resolution
d = D()
print("\nCalling methods:")
d.method()      # Uses B, not C
d.a_only()      # Inherited from A
d.b_only()      # Inherited from B
d.c_only()      # Inherited from C
 
# Use super() to call parent method
class E(B, C):
    def method(self):
        print("E.method")
        super().method()  # Calls next in MRO
 
print("\nWith super():")
E().method()

Common patterns

C3 linearization algorithm:

  • Preserves left-to-right order of parent classes
  • Respects parent class ordering
  • Ensures each class appears only once
  • Result: Class → B → C → A → object

Viewing MRO:

  • ClassName.__mro__: tuple of classes in resolution order
  • ClassName.mro(): method returning list of classes
  • help(ClassName): shows MRO in documentation

The super() function:

  • Calls next method in MRO (not necessarily parent class)
  • super().method(): calls next class's method
  • Essential for cooperative multiple inheritance
  • Uses MRO to find what's “next”

Cooperative multiple inheritance (best practice):

  • All classes call super() in the chain
  • Allows multiple inheritance to work smoothly
  • Each class should accept **kwargs to pass through unknown args
  • Results in diamond inheritance working correctly

Common mistakes:

  • Assuming super() calls parent class (it actually calls next in MRO)
  • Not calling super().__init__() in subclass (skips parent initialization)
  • Mixing super() and direct parent calls (breaks MRO chain)

Diamond problem (solved by C3):

    A
   / \
  B   C
   \ /
    D
  • D inherits from B and C, both inherit from A
  • C3 ensures A is called only once, at the end
  • MRO: D → B → C → A → object
python-mro.md · Last modified: by 127.0.0.1