π 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)