🚀 Introduction
In Python, super() is essential for calling methods from parent classes, especially in multiple inheritance. It ensures that:
✅ Parent class methods are called properly
✅ All necessary initializations happen in the correct order
✅ We avoid redundant calls to parent classes
In this post, we’ll cover:
✔️ How super() works internally
✔️ Using super() in single and multiple inheritance
✔️ Understanding MRO (Method Resolution Order) in super()
✔️ Common pitfalls and best practices
1️⃣ Understanding super() – What Does It Do?
🔹 super() returns a proxy object that delegates method calls to a parent or sibling class.
🔹 Basic Example – Calling Parent Class Method
class Parent:
def greet(self):
print("Hello from Parent!")
class Child(Parent):
def greet(self):
super().greet() # Calls Parent's method
print("Hello from Child!")
c = Child()
c.greet()
🔹 Output:
Hello from Parent!
Hello from Child!
✅ super().greet() calls Parent.greet(), ensuring both methods execute correctly.
2️⃣ Using super() in init() Methods
🔹 Without super() – Manual Calling of Parent init()
class A:
def __init__(self):
print("Initializing A")
class B(A):
def __init__(self):
print("Initializing B")
A.__init__(self) # Manually calling A’s __init__
b = B()
🔹 Output:
Initializing B
Initializing A
❌ Problem:
Manually calling A.__init__(self) is not scalable for multiple inheritance.
🔹 Using super() – The Right Way
class A:
def __init__(self):
print("Initializing A")
class B(A):
def __init__(self):
print("Initializing B")
super().__init__() # Calls A’s __init__
b = B()
✅ Why Use super()?
Handles multiple inheritance correctly.
Automatically follows MRO to prevent redundant calls.
3️⃣ super() in Multiple Inheritance (MRO in Action)
🔹 The Diamond Problem in Multiple Inheritance
class A:
def __init__(self):
print("Initializing A")
class B(A):
def __init__(self):
print("Initializing B")
super().__init__()
class C(A):
def __init__(self):
print("Initializing C")
super().__init__()
class D(B, C): # Multiple inheritance
def __init__(self):
print("Initializing D")
super().__init__()
d = D()
🔹 Output (following MRO):
Initializing D
Initializing B
Initializing C
Initializing A
✅ Why does this order occur?
print(D.mro())
# [D, B, C, A, object]
super() ensures all parent classes are initialized exactly once.
MRO determines the order: D → B → C → A → object.
4️⃣ When Not to Use super()
🔹 Using super() When Parent Class Does Not Have the Method
class A:
pass
class B(A):
def greet(self):
super().greet() # ❌ ERROR: A does not have greet()
b = B()
b.greet() # AttributeError: 'super' object has no attribute 'greet'
✅ Fix: Always check if the parent defines the method before calling super().
5️⃣ Common Pitfalls and Best Practices
✅ Always Use super() Instead of Explicit Parent Calls
class Parent:
def greet(self):
print("Hello from Parent!")
class Child(Parent):
def greet(self):
Parent.greet(self) # ❌ Avoid this!
✔️ Correct Way:
class Child(Parent):
def greet(self):
super().greet() # ✅ This follows MRO
✅ Always Call super().init() in init()
class Parent:
def __init__(self):
print("Parent initialized")
class Child(Parent):
def __init__(self):
print("Child initialized")
super().__init__()
c = Child()
✔️ Ensures parent class is properly initialized.
✅ Check MRO Before Using super() in Multiple Inheritance
print(ClassName.mro()) # Helps debug method resolution issues
✅ Use super() Consistently Across a Class Hierarchy
If some classes use super() but others don’t, unexpected behavior may occur.
6️⃣ Summary
✔️ super() calls methods from parent classes following MRO.
✔️ In multiple inheritance, super() ensures each class is called only once.
✔️ Use super() in init() to ensure proper initialization.
✔️ Avoid manually calling parent methods—use super() instead!
🚀 What’s Next?
Next, we'll explore Python’s Abstract Base Classes (ABC) and enforcing class structures! Stay tuned.