Home/Learn/Python A–Z/Inheritance, super() & the MRO

Inheritance, super() & the MRO

Intermediate
OOP

Subclasses extend or override parent behaviour; super() delegates up the Method Resolution Order — a C3-linearized chain that makes even multiple inheritance deterministic.

Overview

Python inheritance is Java-like at the surface — subclass, override, call super() — but with two twists. First, super().__init__() is not called automatically: forget it and the parent state never initializes. Second, Python allows MULTIPLE inheritance, tamed by the MRO (Method Resolution Order): a C3-linearized, left-to-right order that every attribute lookup and super() call follows. You can inspect it (Class.__mro__), and understanding it separates candidates who memorize from those who understand.

Single Inheritance & super()

Override by redefining; extend by overriding AND calling super(). isinstance() checks the whole chain.

Override + extend with super()
class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    def payslip(self):
        return f"{self.name}: {self.salary}"

class Engineer(Employee):
    def __init__(self, name, salary, stack):
        super().__init__(name, salary)   # REQUIRED — not automatic!
        self.stack = stack

    def payslip(self):                    # extend, not replace
        return super().payslip() + f" [{self.stack}]"

e = Engineer("Asha", 12_00_000, "Python")
print(e.payslip())            # Asha: 1200000 [Python]
print(isinstance(e, Employee))   # True
print(issubclass(Engineer, Employee))  # True

Multiple Inheritance & MRO

With class D(B, C), lookups go D → B → C → base (C3 linearization). super() follows the MRO — not simply "my parent" — which is how cooperative mixins chain.

Mixins compose via the MRO
class JSONMixin:
    def to_json(self):
        import json
        return json.dumps(self.__dict__)

class TimestampMixin:
    def __init__(self, **kwargs):
        from datetime import datetime, timezone
        self.created_at = datetime.now(timezone.utc).isoformat()
        super().__init__(**kwargs)      # cooperative — passes along MRO

class Model:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

class User(TimestampMixin, JSONMixin, Model):
    pass

u = User(name="Ravi")
print(u.to_json())     # {"created_at": "...", "name": "Ravi"}

print([c.__name__ for c in User.__mro__])
# ['User', 'TimestampMixin', 'JSONMixin', 'Model', 'object']
# super() in TimestampMixin called Model.__init__ — via the MRO

Key Points to Remember

  • 1super().__init__() must be called explicitly — Python will not do it for you
  • 2MRO = deterministic lookup order (C3); inspect with Class.__mro__
  • 3super() follows the MRO, not literally "the parent" — that is what makes mixins work
  • 4Prefer shallow hierarchies + composition; mixins for orthogonal features

Interview Questions

Sign in to ask Aria
1

What is the MRO and why does Python need it? How do you inspect it?

MediumCRED
2

What happens if a subclass defines __init__ but never calls super().__init__()?

MediumInfosys
3

Explain the diamond problem and how C3 linearization resolves it.

HardGoogle

Ask Aria about Inheritance, super() & the MRO

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…