datarekha
Python Medium Asked at GoogleAsked at MetaAsked at Stripe

How does `super()` work in Python, and why is the zero-argument form preferred over `super(ClassName, self)`?

The short answer

`super()` returns a proxy that delegates method calls to the next class in the MRO, not necessarily the direct parent. The zero-argument form `super()` (Python 3) is preferred because it uses a compiler-injected `__class__` cell, which correctly tracks the defining class even under multiple inheritance — avoiding the brittle repetition of the class name.

How to think about it

What’s really being tested

The interviewer wants to see whether you understand that super() is not just a synonym for “call the parent.” It’s about the Method Resolution Order (MRO) — the linearised list of classes Python uses to look up methods. That distinction is invisible in single inheritance but becomes critical the moment you have a diamond-shaped class hierarchy.

Single inheritance — the easy case

Start here because it’s intuitive. super().__init__() just calls Animal.__init__ from inside Dog:

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)   # delegates to Animal.__init__
        self.breed = breed

This works and everyone understands it. The interesting case is multiple inheritance.

Multiple inheritance — why “next in MRO” matters

When class D inherits from both B and C, and both inherit from A, Python needs to ensure A.__init__ is called exactly once. The MRO for D is [D, B, C, A, object]. Each class’s super() call walks to the next entry in that list — not its own parent.

Without super() in B and C, C.setup or A.setup would be skipped entirely, or A.setup would run twice. super() makes cooperative inheritance possible.

Zero-argument vs explicit form

# Python 3 — preferred
super().__init__(name)

# Python 2 / explicit form — error-prone
super(Dog, self).__init__(name)

The explicit form hardcodes the class name. If you rename Dog, copy the method to a subclass, or refactor the hierarchy, that hardcoded name breaks silently or raises a confusing TypeError at runtime. The zero-argument form uses __class__, a read-only closure variable injected by the compiler at method definition time. It always refers to the class that textually defines the method, regardless of what self is at runtime.

Learn it properly Inheritance vs Composition

Keep practising

All Python questions

Explore further

Skip to content