DEV Community

Bharathvaj
Bharathvaj

Posted on • Originally published at bharathvaj.com

Python's __mro__

Python's __mro__ (Method Resolution Order) is a crucial concept that determines how Python looks up methods in inheritance hierarchies. Let's dive into what it is, why we need it, and see it in action.

๐Ÿ” What is mro?

__mro__ is a tuple that defines the order in which Python searches for methods and attributes in a class hierarchy. Every class has this attribute, showing its linearized inheritance path.

class Animal:
    pass

class Dog(Animal):
    pass

print(Dog.__mro__)
# (<class '__main__.Dog'>, <class '__main__.Animal'>, <class 'object'>)
Enter fullscreen mode Exit fullscreen mode

Python searches from left to right: first in Dog, then Animal, finally object.


๐ŸŽฏ Why Do We Need It?

The MRO solves the diamond problem in multiple inheritance - when a class inherits from multiple classes that share a common ancestor.

class A:
    def method(self):
        return "A"

class B(A):
    def method(self):
        return "B"

class C(A):
    def method(self):
        return "C"

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

d = D()
print(d.method())  # "B" - follows MRO
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
Enter fullscreen mode Exit fullscreen mode

Without MRO, Python wouldn't know whether to call B.method() or C.method(). The MRO provides a consistent, predictable order using the C3 linearization algorithm.


๐Ÿ’ก Practical Use Cases

1. Super() in Cooperative Inheritance

super() follows the MRO, not just the parent class. This enables cooperative multiple inheritance:

class Logger:
    def save(self):
        print("Logging...")
        super().save()  # Continues MRO chain

class Database:
    def save(self):
        print("Saving to database...")

class Model(Logger, Database):
    def save(self):
        print("Validating...")
        super().save()  # Calls Logger.save()

model = Model()
model.save()
# Output:
# Validating...
# Logging...
# Saving to database...
Enter fullscreen mode Exit fullscreen mode

2. Mixin Classes

MRO makes mixins powerful by ensuring methods are called in the right order:

class TimestampMixin:
    def save(self):
        self.updated_at = "2025-08-11"
        super().save()

class ValidationMixin:
    def save(self):
        if not hasattr(self, 'name'):
            raise ValueError("Name required")
        super().save()

class BaseModel:
    def save(self):
        print(f"Saving {self.name} at {self.updated_at}")

class User(ValidationMixin, TimestampMixin, BaseModel):
    def __init__(self, name):
        self.name = name

user = User("Alice")
user.save()  # Validates, adds timestamp, then saves
# Output: Saving Alice at 2025-08-11
Enter fullscreen mode Exit fullscreen mode

3. Framework Method Overriding

Web frameworks like Django use MRO to let you override specific behaviors while keeping others:

class BaseView:
    def get(self):
        return self.render()

    def render(self):
        return "Base rendering"

class AuthMixin:
    def get(self):
        if not self.is_authenticated():
            return "Login required"
        return super().get()

    def is_authenticated(self):
        return False

class MyView(AuthMixin, BaseView):
    def render(self):
        return "Custom rendering"

view = MyView()
print(view.get())  # "Login required" - AuthMixin.get() runs first
print(MyView.__mro__)
# Shows: MyView -> AuthMixin -> BaseView -> object
Enter fullscreen mode Exit fullscreen mode

๐Ÿš€ Key Takeaways

  • __mro__ defines the method lookup order in inheritance hierarchies
  • It solves the diamond problem using C3 linearization
  • Order matters in multiple inheritance: class Child(Parent1, Parent2) searches Parent1 before Parent2
  • super() follows the MRO, not just the immediate parent
  • Understanding MRO is essential for designing effective mixin classes and using frameworks

Remember: when in doubt, check YourClass.__mro__ to see the exact lookup order!

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.