🚀 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.

💬 Got questions? Drop them in the comments! 🚀