Here are 10 Python snippets to demonstrate Method Resolution Order (MRO) and how Python determines the order of method calls in multi-level and multiple inheritance scenarios:
1. Basic MRO in Single Inheritance
classA:defmethod(self):return"Method from A"classB(A):passb =B()print(b.method())# Output: Method from A
2. Overriding a Method
classA:defmethod(self):return"Method from A"classB(A):defmethod(self):return"Method from B"b =B()print(b.method())# Output: Method from B
3. Multi-Level Inheritance
4. Diamond Problem in Multiple Inheritance
5. Using super() in MRO
6. Checking MRO with __mro__
7. Complex MRO with Multiple Inheritance
8. Reordering Base Classes
9. MRO with super() in Multiple Inheritance
10. Using inspect.getmro
Key Points About MRO:
MRO stands for Method Resolution Order, the order in which Python looks for methods in a hierarchy of classes.
Python uses the C3 Linearization Algorithm to determine the MRO in case of multiple inheritance.
You can check the MRO of a class using:
ClassName.__mro__
inspect.getmro(ClassName)
help(ClassName)
super() is resolved according to the MRO, making it easier to call parent class methods dynamically in a predictable order.
These examples illustrate how Python handles MRO, even in complex inheritance scenarios.
class A:
def method(self):
return "Method from A"
class B(A):
pass
class C(B):
pass
c = C()
print(c.method()) # Output: Method from A
class A:
def method(self):
return "Method from A"
class B(A):
def method(self):
return "Method from B"
class C(A):
pass
class D(B, C):
pass
d = D()
print(d.method()) # Output: Method from B
class A:
def method(self):
return "Method from A"
class B(A):
def method(self):
return super().method() + " and B"
class C(B):
def method(self):
return super().method() + " and C"
c = C()
print(c.method()) # Output: Method from A and B and C
class A:
pass
class B(A):
pass
class C(B):
pass
print(C.__mro__)
# Output: (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(A, B):
pass
c = C()
print(c.method()) # Output: Method from A
print(C.__mro__)
# Output: (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
class A:
def method(self):
return "Method from A"
class B:
def method(self):
return "Method from B"
class C(B, A): # B is listed before A
pass
c = C()
print(c.method()) # Output: Method from B
print(C.__mro__)
# Output: (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
class A:
def method(self):
return "Method from A"
class B(A):
def method(self):
return super().method() + " and B"
class C(A):
def method(self):
return super().method() + " and C"
class D(B, C):
def method(self):
return super().method() + " and D"
d = D()
print(d.method()) # Output: Method from A and C and B and D
print(D.__mro__)
# Output: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
import inspect
class A:
pass
class B(A):
pass
class C(B):
pass
print(inspect.getmro(C))
# Output: (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)