How to Call Parent Constructors in Python

I have been writing Python code for over years now, and I still remember the first time I wrestled with class inheritance.

Once I discovered how to use the super constructor properly, everything changed in my development workflow.

Inheritance is a cornerstone of Object-Oriented Programming (OOP), allowing us to build complex systems by building on top of existing code.

The super() function is the secret sauce that makes this process seamless and professional. In this tutorial, I will show you exactly how to call the super constructor in Python using my firsthand experience from years of software engineering.

What is the Super Constructor in Python?

When you create a child class that inherits from a parent class, the child class often needs to run the initialization code of the parent.

This initialization code is located in the __init__ method, which we commonly refer to as the constructor.

The super() function returns a temporary object of the parent class, allowing you to call its methods.

By calling super().__init__(), you ensure that the parent class is properly set up before the child class adds its own specific logic.

In my experience, skipping this step is one of the most common causes of bugs in Python applications.

Basic Single Inheritance: The US Employee Example

Let’s look at a practical example involving an employee management system for a company based in New York. We have a base class for a general employee and a specific class for a software developer.

I always prefer using super() because it keeps the code “DRY” (Don’t Repeat Yourself).

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        print(f"Initializing Employee: {self.name}")

class Developer(Employee):
    def __init__(self, name, salary, programming_language):
        # Calling the parent constructor using super()
        super().__init__(name, salary)
        self.programming_language = programming_language
        print(f"Setting language to {self.programming_language} for {self.name}")

# Creating an instance of Developer
dev = Developer("Alice Smith", 125000, "Python")

# Verifying the attributes
print(f"Employee Name: {dev.name}")
print(f"Annual Salary: ${dev.salary:,}")
print(f"Primary Skill: {dev.programming_language}")

I executed the above example code and added the screenshot below.

python call super constructor

In the code above, the Developer class doesn’t need to manually assign self.name or self.salary.

It simply “asks” the Employee class to handle those basic details via super().__init__(name, salary).

Pass Arguments to the Super Constructor

In many real-world USA business scenarios, you need to pass specific configuration data up the inheritance chain.

Imagine a logistics company in Chicago managing a fleet of delivery vehicles.

Each vehicle has a VIN (Vehicle Identification Number), but a truck has an additional “towing capacity.”

I’ve found that passing arguments correctly is vital when your parent classes become more complex.

class Vehicle:
    def __init__(self, vin, make):
        self.vin = vin
        self.make = make
        print(f"Vehicle registered with VIN: {self.vin}")

class Truck(Vehicle):
    def __init__(self, vin, make, towing_capacity):
        # Pass vin and make to the Vehicle constructor
        super().__init__(vin, make)
        self.towing_capacity = towing_capacity
        print(f"Truck capacity set to {self.towing_capacity} lbs")

# Instantiate a Freightliner truck
my_truck = Truck("1A2B3C4D5E6F", "Freightliner", 30000)

print(f"Make: {my_truck.make}")
print(f"Towing Capacity: {my_truck.towing_capacity} lbs")

I executed the above example code and added the screenshot below.

python call parent constructor

By using super(), I am ensuring that the Vehicle class handles the VIN registration perfectly.

If I ever decide to change how VINs are validated in the Vehicle class, I only have to change it in one place.

Handle Multiple Inheritance with super()

One of the most powerful, and sometimes confusing, features of Python is multiple inheritance. This is where a class inherits from more than one parent class.

Python uses something called Method Resolution Order (MRO) to decide which parent class to call first.

I’ve used this frequently when building complex financial systems where a “User” might be both a “Customer” and an “Admin.”

class User:
    def __init__(self, email):
        self.email = email
        print(f"User email set to {self.email}")

class Customer(User):
    def __init__(self, email, loyalty_id):
        super().__init__(email)
        self.loyalty_id = loyalty_id
        print(f"Customer ID set to {self.loyalty_id}")

class Admin(User):
    def __init__(self, email, access_level):
        super().__init__(email)
        self.access_level = access_level
        print(f"Admin access level: {self.access_level}")

class SuperUser(Customer, Admin):
    def __init__(self, email, loyalty_id, access_level):
        # super() handles the MRO automatically
        super().__init__(email, loyalty_id)
        # We handle the extra Admin attribute manually here or via specialized design
        self.access_level = access_level
        print("SuperUser fully initialized")

# Creating a SuperUser for a California-based retail app
power_user = SuperUser("jordan@example.com", "LOYAL-99", "Full_Access")

When you use super() in multiple inheritance, Python follows a specific path defined by the __mro__ attribute.

This prevents the “Diamond Problem,” where a base class constructor might accidentally be called twice.

In my years of coding, relying on Python’s built-in MRO has saved me from countless hours of debugging.

Why Not Just Call the Parent Class Directly?

You might wonder why we don’t just use Employee.__init__(self, name, salary).

While this works in simple cases, it is considered a bad practice in modern Python.

I’ve seen junior developers do this often, and it usually leads to hard-to-find bugs in complex projects.

Directly naming the parent class makes your code “brittle,” meaning if you rename the parent, you have to find and replace every call.

More importantly, direct calls do not support the Method Resolution Order we discussed earlier.

Using super() makes your code more maintainable and cooperative with other classes.

The Old Way vs. The New Way

If you are looking at older Python 2 codebases, you might see super(Developer, self).__init__(name, salary).

In the past, we had to explicitly tell super() which class we were in and provide the self instance.

Since Python 3 was released, we can simply use super()._init__(), which is much cleaner.

As someone who transitioned through both versions, I can tell you the new syntax is a huge quality-of-life improvement.

Always use the short version unless you are specifically forced to work in a legacy Python 2 environment.

Real-World Example: US Real Estate Tax Calculator

Let’s look at a more complex example that feels like a real professional task. Suppose we are building a tool for a real estate firm in Texas to calculate property taxes.

We have a base Property class and a CommercialProperty subclass.

class Property:
    def __init__(self, address, market_value):
        self.address = address
        self.market_value = market_value
        self.tax_rate = 0.02  # Standard 2% tax rate
        print(f"Processing property at: {self.address}")

    def calculate_tax(self):
        return self.market_value * self.tax_rate

class CommercialProperty(Property):
    def __init__(self, address, market_value, business_type):
        # Initialize the base property attributes
        super().__init__(address, market_value)
        self.business_type = business_type
        # Commercial properties have a higher tax rate in this county
        self.tax_rate = 0.035 
        print(f"Type: Commercial ({self.business_type})")

# Example for a warehouse in Dallas
warehouse = CommercialProperty("123 Logistics Way, Dallas, TX", 2500000, "Industrial")

tax_amount = warehouse.calculate_tax()
print(f"Total Property Tax: ${tax_amount:,.2f}")

I executed the above example code and added the screenshot below.

python super constructor

In this case, super() allowed us to set the address and value through the standard logic. Then, we were able to immediately override the tax_rate specifically for commercial needs.

This structure is exactly how I build scalable applications that are easy for other developers to read.

Best Practices for Using super()

Through the years, I have developed a few “golden rules” for using constructors:

  1. Always call super(): Even if the parent class doesn’t do much now, it’s safer for future changes.
  2. Match the signatures: Ensure the arguments you pass to super() match what the parent __init__ expects.
  3. Use keyword arguments: If you have many parameters, using **kwargs can make your super() calls more flexible.
  4. Order matters: Generally, call super().__init__() at the very beginning of your child constructor.

Following these rules will help you write “Pythonic” code that stands up to professional scrutiny.

Common Errors to Avoid

The most common error I see is forgetting to pass self when using the old Python 2 style.

Another mistake is forgetting to pass the required arguments that the parent class expects.

If the parent class requires a username but you only pass password to super(), Python will raise a TypeError.

I always recommend double-checking the parent class’s __init__ method before writing your child class.

In this tutorial, you learned how to use the super() function to call parent constructors in Python.

We covered basic inheritance, passing arguments, and how Python handles multiple parent classes using MRO.

I hope you found this guide helpful and can use these examples in your own Python projects.

Using super() correctly is a major step toward becoming a senior-level Python developer.

You may also read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.