`super()` — calling parent methods
WHAT is super()?
So instead of:
class Dog(Animal):
def __init__(self, name):
Animal.__init__(self, name) # hard-coded parent nameyou write:
class Dog(Animal):
def __init__(self, name):
super().__init__(name) # decoupled from parent nameWHY does it exist? (the problem it solves)
HOW it works — derived from first principles
There is no magic. super() is just Parent.method(self) but with the parent chosen dynamically via the MRO.
Step 1 — every class has an MRO. Python computes a linear order of classes to search for an attribute. View it:
Dog.__mro__ # (Dog, Animal, object)Step 2 — super() inside a method of class C means:
"Start searching the MRO of
type(self)at the position right afterC, and bindself."
Step 3 — derive the equivalence. Inside Dog.__init__, super() is conceptually:
which finds the next class after Dog in type(self).__mro__ (here Animal) and calls its method with self already supplied. That's why you write super().__init__(name) and not super().__init__(self, name) — self is injected automatically.

Worked Example 1 — extending __init__
class Animal:
def __init__(self, name):
self.name = name
self.legs = 4
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # parent sets name + legs
self.breed = breed # child adds extra state
d = Dog("Rex", "Lab")
print(d.name, d.legs, d.breed) # Rex 4 Lab- Why
super().__init__(name)first? Soself.nameandself.legsexist before the child adds its own attributes — child extends, doesn't replace. - Why no
self? The proxy already boundself; passing it again gives a "got multiple values for argument" error.
Worked Example 2 — extending a normal method
class Logger:
def save(self, data):
print("validating", data)
return True
class TimestampLogger(Logger):
def save(self, data):
ok = super().save(data) # reuse parent's validation
print("saved at 12:00", data)
return ok- Why call
super().saveinstead of copying validation? If validation logic changes inLogger, the child stays correct automatically (single source of truth).
Worked Example 3 — multiple inheritance & the MRO
class A:
def __init__(self): print("A"); super().__init__()
class B(A):
def __init__(self): print("B"); super().__init__()
class C(A):
def __init__(self): print("C"); super().__init__()
class D(B, C):
def __init__(self): print("D"); super().__init__()
D() # prints D B C A (each ONCE)
print([c.__name__ for c in D.__mro__]) # D B C A object- Why
D B C Aand notD B A C A? Becausesuper()inBdoes not mean "go toA" — it means "go to the next class inD's MRO," which isC. The MRO guaranteesAruns exactly once. This is the killer feature you can't get withA.__init__(self).
Recall Feynman: explain to a 12-year-old
Imagine your dad has a recipe for soup. You want to make the same soup but add cheese on top. Instead of writing the whole recipe again, you say "Dad, make your soup" (super()), and then you sprinkle cheese. If Dad improves his soup, yours gets better too — for free. super() is just calling "the person above me in the family line" to do their part of the job first.
Flashcards
What does super() return?
Why write super().__init__(name) and not super().__init__(self, name)?
self; passing it again causes "multiple values for argument self".In multiple inheritance, does super() mean "the parent class"?
type(self).__mro__, which can be a sibling.What happens if you override __init__ and never call super().__init__()?
AttributeError later.For class D(B,C) with B(A), C(A), what is D's MRO?
Why does using super() in a diamond run the base class only once?
super() advances through the single linearized MRO, so each class is visited exactly once.One concrete advantage of super() over Parent.__init__(self)?
Connections
- Inheritance — extending classes
- Method Resolution Order (MRO) & C3 Linearization
- Method Overriding vs Overloading
- Multiple Inheritance & the Diamond Problem
- `__init__` — constructors
- Composition over Inheritance
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, super() ka matlab simple hai: jab child class apne parent ka koi method (jaise __init__) override karti hai, par parent wala kaam bhi chahiye, tab hum super() use karte hain. Jaise super().__init__(name) — yeh parent ka constructor chala deta hai, taaki parent wali attributes (self.name, self.legs) set ho jayein, aur fir child apni extra cheezein add karti hai. Tum parent ka naam likhne ke bajaye super() likhte ho, isse code decoupled rehta hai — kal ko parent ka naam badla ya beech mein nayi class daali, to bhi code break nahi hoga.
Sabse badi galti jo students karte hain: super().__init__(self, name) likhna. Yeh galat hai kyunki super() already self ko bind kar chuka hota hai, to sirf baaki arguments do — super().__init__(name). Dusri galti: super().__init__() call hi na karna, jisse parent ki setup hi nahi hoti aur baad mein AttributeError aata hai.
Asli power dikhti hai multiple inheritance mein. super() parent ko nahi, balki MRO ka agla class ko bulaata hai. Diamond shape (D se B,C; B,C se A) mein super() har class ko exactly ek baar chalata hai — order D B C A. Agar tum A.__init__(self) directly call karte to A do baar chal jata, jo bug hai. Isliye hamesha super() use karo, MRO sambhal lega.
Yaad rakho: "super has no self" aur "super = next in MRO, not always parent." Bas itna pakka kar lo, exam aur real projects dono mein kaam aayega.