Python super() Function
1. Introduction to super()
The super() function in Python is used to call methods from a parent class in an inheritance hierarchy. It helps in maintaining code reusability, avoiding redundant code, and properly managing multiple inheritance scenarios.
Why do we need super()?
- Method Overriding: When a child class overrides a method from its parent,
super()allows calling the parent’s version of the method. - Extending Parent Methods: It allows calling the parent method without hardcoding the parent class name.
- Constructor Chaining: Helps in calling the constructor (
__init__) of the parent class when initializing a subclass. - Multiple Inheritance Management: Ensures proper order of method execution when dealing with multiple base classes.
2. Basic Usage of super()
Example 1: Calling Parent Class Method
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self):
super().greet() # Calls the parent class method
print("Hello from Child")
# Create an instance of Child
c = Child()
c.greet()
Output:
Hello from Parent
Hello from Child
What happens here?
- The
Childclass overrides thegreet()method of theParentclass. - Inside the
Childclass’sgreet(),super().greet()calls the parent’sgreet()method before executing the child’s version. - This ensures both versions of
greet()are executed.
Why use super() instead of Parent.greet(self)?
Using super() dynamically resolves the method to call based on Method Resolution Order (MRO), which is crucial in multiple inheritance.
3. Calling Parent Constructor with super()
When a subclass defines its own constructor (__init__), the parent class’s constructor is not automatically called. We must use super().__init__() to ensure proper initialization.
Example 2: Using super() to Call Parent Constructor
class Animal:
def __init__(self, species):
self.species = species
print(f"Animal created: {species}")
class Dog(Animal):
def __init__(self, name, breed):
super().__init__("Dog") # Calls the Parent class constructor
self.name = name
self.breed = breed
print(f"Dog created: {name}, Breed: {breed}")
# Creating a Dog instance
d = Dog("Buddy", "Golden Retriever")
Output:
Animal created: Dog
Dog created: Buddy, Breed: Golden Retriever
Explanation:
- The
Dogclass has its own constructor that takesnameandbreedas arguments. - The
super().__init__("Dog")call ensures that the Animal class constructor is executed first. - This allows the
speciesattribute (fromAnimal) to be initialized properly before setting upnameandbreedinDog.
4. Understanding Method Resolution Order (MRO)
Python follows a special order when resolving method calls in an inheritance hierarchy. This is known as the Method Resolution Order (MRO).
How to Check MRO?
You can check the MRO using:
print(ClassName.mro())
or
help(ClassName)
Example 3: Checking MRO
class A:
def show(self):
print("A's method")
class B(A):
def show(self):
print("B's method")
super().show()
class C(B):
def show(self):
print("C's method")
super().show()
c = C()
c.show()
print(C.mro()) # Prints Method Resolution Order
Output:
C's method
B's method
A's method
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
Key Points
super().show()inCcallsshow()fromB, which then callsshow()fromA.- MRO follows the order
[C → B → A → object]. objectis the ultimate parent of all classes in Python.
5. super() in Multiple Inheritance
Example 4: Multiple Inheritance with super()
class A:
def show(self):
print("A's method")
class B(A):
def show(self):
print("B's method")
super().show()
class C(A):
def show(self):
print("C's method")
super().show()
class D(B, C): # Multiple inheritance
def show(self):
print("D's method")
super().show()
d = D()
d.show()
Output:
D's method
B's method
C's method
A's method
MRO for Class D
print(D.mro())
Output:
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
Key Observations
- Order is D → B → C → A because Python uses C3 Linearization to maintain consistency.
super()ensures that each class is called only once, avoiding duplicate calls toA.
6. Calling super() with Arguments
Example 5: Passing Arguments
class Parent:
def __init__(self, name):
print(f"Parent constructor called for {name}")
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # Passing 'name' to the Parent constructor
print(f"Child constructor called for {name}, Age: {age}")
c = Child("Alice", 10)
Output:
Parent constructor called for Alice
Child constructor called for Alice, Age: 10
Key Points
- Arguments passed to
super()are forwarded to the parent class constructor. - This ensures that all necessary attributes are initialized properly.
7. super() in Static and Class Methods
Example 6: Using super() in Class Methods
class Parent:
@classmethod
def greet(cls):
print(f"Hello from {cls.__name__}")
class Child(Parent):
@classmethod
def greet(cls):
super().greet()
print(f"Hello from {cls.__name__}")
Child.greet()
Output:
Hello from Parent
Hello from Child
Why does super() work in class methods?
- Since class methods receive
clsinstead ofself,super()correctly resolves methods for the class.
8. Common Mistakes with super()
Calling super() in a class without a parent
class A:
def method(self):
super().method() # ERROR: No parent class
Solution: Only use super() in classes that inherit from another.
Forgetting super().__init__() in inheritance
class A:
def __init__(self):
print("A initialized")
class B(A):
def __init__(self):
print("B initialized") # Forgot super().__init__()
b = B()
Fix: Use super().__init__() inside B.__init__().
9. Summary
super()calls parent class methods dynamically.- Works with single and multiple inheritance.
- Resolves methods using Method Resolution Order (MRO).
- Used in constructors, instance methods, class methods, and static methods.