2.1.9OOP Fundamentals

`super()` — calling parent methods

1,550 words7 min readdifficulty · medium

WHAT is super()?

So instead of:

class Dog(Animal):
    def __init__(self, name):
        Animal.__init__(self, name)   # hard-coded parent name

you write:

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)        # decoupled from parent name

WHY 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 after C, and bind self."

Step 3 — derive the equivalence. Inside Dog.__init__, super() is conceptually: super()super(Dog, self)\texttt{super()} \equiv \texttt{super(Dog, self)} 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.

Figure — `super()` — calling parent methods

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? So self.name and self.legs exist before the child adds its own attributes — child extends, doesn't replace.
  • Why no self? The proxy already bound self; 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().save instead of copying validation? If validation logic changes in Logger, 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 A and not D B A C A? Because super() in B does not mean "go to A" — it means "go to the next class in D's MRO," which is C. The MRO guarantees A runs exactly once. This is the killer feature you can't get with A.__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?
A proxy object that delegates method calls to the next class in the current object's MRO (after the current class).
Why write super().__init__(name) and not super().__init__(self, name)?
The proxy already binds self; passing it again causes "multiple values for argument self".
In multiple inheritance, does super() mean "the parent class"?
No — it means the next class in type(self).__mro__, which can be a sibling.
What happens if you override __init__ and never call super().__init__()?
Parent attributes are never initialized → likely AttributeError later.
For class D(B,C) with B(A), C(A), what is D's MRO?
D, B, C, A, object.
Why does using super() in a diamond run the base class only once?
Because each super() advances through the single linearized MRO, so each class is visited exactly once.
One concrete advantage of super() over Parent.__init__(self)?
Decoupling — renaming/reordering the hierarchy doesn't break the call.

Connections

Concept Map

still needs

delegates to

walks

starts after

enables

gives

ensures

visited once each

binds

so omit self in

derived from

finds next in

Child overrides method

super() proxy object

MRO - Method Resolution Order

Parent implementation

Extend not replace behaviour

No hard-coded parent name

Diamond inheritance correctness

self injected automatically

super() == super(Dog, self)

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.

Go deeper — visual, from zero

Test yourself — OOP Fundamentals

Connections