Inheritance is one of those foundational concepts in Python that can either make your life very easy or incredibly frustrating.
In my decade of building backend systems, I’ve seen many developers struggle when they need to pass data from a child class up to a parent class.
Specifically, when the parent class requires arguments in its __init__ method, you have to be precise about how you handle the super() call.
In this tutorial, I’ll show you exactly how to call super constructors with arguments using real-world scenarios you’d actually encounter in a professional environment.
The Need for Passing Arguments to Parent Classes
When you create a subclass in Python, it doesn’t automatically call the __init__ method of the parent class if you define an __init__ in the child.
If the parent class needs specific data—like a database connection string or a user’s social security number—you must pass that data up manually.
I remember working on a payroll system for a US-based tech firm where we had a base Employee class and specialized Contractor and FullTime classes.
Without correctly passing arguments to the super() constructor, the base employee ID and tax information would never get initialized, crashing the entire pay cycle.
Method 1: The Standard super() Call with Positional Arguments
The most common way to handle this is by using the super() function inside the child’s __init__ method.
I prefer this method because it’s clean and follows the Method Resolution Order (MRO) that Python uses under the hood.
Let’s look at an example involving a Federal Tax calculation system. We have a base class for a generic Tax Filer and a subclass for a Head of Household.
# Base class representing a general US Tax Filer
class TaxFiler:
def __init__(self, full_name, ssn):
self.full_name = full_name
self.ssn = ssn
print(f"Base Profile Created for: {self.full_name}")
# Subclass for Head of Household filing status
class HeadOfHousehold(TaxFiler):
def __init__(self, full_name, ssn, dependents_count):
# Calling the parent constructor with arguments
super().__init__(full_name, ssn)
self.dependents_count = dependents_count
print(f"Filing Status: Head of Household with {self.dependents_count} dependents.")
# Implementation
filer_one = HeadOfHousehold("James Anderson", "999-00-1234", 3)
print(f"Name: {filer_one.full_name}")
print(f"SSN: {filer_one.ssn}")
print(f"Dependents: {filer_one.dependents_count}")You can refer to the screenshot below to see the output.

In this snippet, notice how HeadOfHousehold takes three arguments, but it only keeps one for itself.
It passes full_name and ssn up to the TaxFiler class using super().__init__(full_name, ssn).
Method 2: Use Keyword Arguments for Clarity
When you are dealing with complex US real estate data or financial models, positional arguments can get confusing.
I often find that using keyword arguments makes the code much more readable for other developers on the team.
If you have a base class for a Property in New York and a subclass for a CommercialLease, using keywords prevents passing the square footage into the price field by mistake.
class Property:
def __init__(self, address, zip_code, state="NY"):
self.address = address
self.zip_code = zip_code
self.state = state
class CommercialLease(Property):
def __init__(self, business_name, **kwargs):
# We extract what we need and pass the rest up
super().__init__(address=kwargs.get('address'), zip_code=kwargs.get('zip_code'))
self.business_name = business_name
# Creating an instance using keyword arguments
storefront = CommercialLease(
business_name="Manhattan Coffee Co.",
address="123 Broadway",
zip_code="10001"
)
print(f"Business: {storefront.business_name}")
print(f"Location: {storefront.address}, {storefront.zip_code}, {storefront.state}")You can refer to the screenshot below to see the output.

Using **kwargs allows you to be flexible. If the parent class changes to accept more parameters later, your child class often won’t need a total rewrite.
Method 3: The Traditional ClassName.init Approach
Before super() became the standard in Python 3, we used to call the parent class by its name directly.
While I don’t recommend this for most modern projects, you will definitely see this in older legacy codebases in many US banks and insurance companies.
It requires you to pass self explicitly as the first argument, which super() handles for you automatically.
class InsurancePolicy:
def __init__(self, policy_number, premium):
self.policy_number = policy_number
self.premium = premium
class AutoInsurance(InsurancePolicy):
def __init__(self, policy_number, premium, vehicle_vin):
# Calling parent by name - old school style
InsurancePolicy.__init__(self, policy_number, premium)
self.vehicle_vin = vehicle_vin
# Instance for a Ford F-150 policy
my_truck_policy = AutoInsurance("POL-8821", 1200.50, "1FTEF150XXXXX")
print(f"Policy: {my_truck_policy.policy_number}")
print(f"VIN: {my_truck_policy.vehicle_vin}")You can refer to the screenshot below to see the output.

I usually avoid this because it hard-codes the parent class name. If you decide to change the parent class, you have to update it in every single subclass.
Handle Multiple Inheritance with Arguments
Things get tricky when a child class inherits from two different parents. This is common in complex US Logistics software where a DeliveryVehicle might inherit from both MotorVehicle and Asset.
In these cases, Python’s super() follows the MRO (Method Resolution Order).
To make this work with arguments, all classes in the hierarchy should ideally use **kwargs.
class Vehicle:
def __init__(self, vin, **kwargs):
super().__init__(**kwargs)
self.vin = vin
class Electric:
def __init__(self, battery_capacity, **kwargs):
super().__init__(**kwargs)
self.battery_capacity = battery_capacity
class TeslaSemi(Vehicle, Electric):
def __init__(self, model_name, **kwargs):
super().__init__(**kwargs)
self.model_name = model_name
# Using all arguments for a logistics fleet
truck = TeslaSemi(
model_name="Semi-Gen1",
vin="5YJSA1E2",
battery_capacity="500kWh"
)
print(f"Model: {truck.model_name}")
print(f"VIN: {truck.vin}")
print(f"Battery: {truck.battery_capacity}")This pattern ensures that every __init__ in the chain gets called and only “plucks” the arguments it needs.
Common Mistakes to Avoid
In my experience, the biggest mistake is forgetting to pass an argument that the parent class strictly requires.
If the User class requires an email, and your Admin subclass calls super().__init__() without it, Python will throw a TypeError.
Another mistake is calling super() twice or mixing ClassName.__init__ with super(). This can lead to the parent constructor running twice, which might duplicate database entries or reset counters.
Always ensure the argument names match exactly if you are using keyword arguments. A typo like addrress instead of address will result in None being passed to the parent.
Why super() is Better Than Direct Class Calls
I always tell my junior devs to stick with super(). It makes your code more maintainable and keeps the hierarchy flexible.
It also supports cooperative multiple inheritance, which is a fancy way of saying it ensures every parent gets its turn to initialize.
If you are working on a large-scale application, like a US-based e-commerce platform, using super() correctly is the difference between a clean codebase and a tangled mess of spaghetti code.
Summary of Best Practices
From what I’ve seen over the years, here are the rules of thumb for calling super constructors:
- Use super().__init__(args) for simple, single inheritance.
- Use
**kwargswhen your class hierarchy is complex or likely to change. - Always match the parameter names expected by the parent class.
- Avoid the old ParentName.__init__(self) style unless you are working on very old code.
- Test your object initialization to ensure all attributes are correctly assigned.
In this tutorial, I have shown you several ways to call super constructors with arguments in Python.
Whether you are building a simple script or a complex financial application for the US market, these patterns will help you write better object-oriented code.
You may read:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.