๐ 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.
Top comments (0)