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 orderClassName.mro(): method returning list of classeshelp(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
**kwargsto 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
