Inheritance, super() & the MRO
IntermediateSubclasses 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.
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)) # TrueMultiple 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.
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 MROKey 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 AriaWhat is the MRO and why does Python need it? How do you inspect it?
What happens if a subclass defines __init__ but never calls super().__init__()?
Explain the diamond problem and how C3 linearization resolves it.
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.