Constructors in Python: Types, Examples, and Best Practices

Published: 27 Nov 2025 | Reading Time: 4 min

Table of Contents

Key Takeaways From the Blog

Introduction

Python is an object-oriented programming language, and one of the most fundamental concepts in OOP is the use of a constructor. A Python constructor is a unique class method used for initializing an object. When the object of a class is being created, its constructor is implicitly called to start the class instance variables.

In this article, we will discuss constructors in Python, their types, efficient usage, and a few advanced concepts, such as multiple constructors, instance methods, and the difference between the init and new methods.

What is a Constructor?

A constructor is a special function that is called when an object of a class is created. It initializes the attributes of an object and prepares the object for use. The class constructor in python is always named __init__, and it is called automatically whenever an object is created.

Syntax

Here is the syntax of a constructor in python:

class ClassName:
    def __init__(self, parameter1, parameter2):  # Constructor
        self.attribute1 = parameter1  # Initialization of Attribute1
        self.attribute2 = parameter2  # Initialization of attribute2

Example: Creating a Constructor in Python

Here is an example to create a constructor in python:

class P:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# Creating an object
P1 = P("Deepthi", 22)

print(P1.name)
print(P1.age)

Explanation

Output

Deepthi
22

Example: Counting the Number of Objects of a Class

Here is an example to count the objects of class in python:

class Counter:
    count = 0
    def __init__(self):
        Counter.count += 1

obj1 = Counter()
obj2 = Counter()
print(Counter.count)  # Output: 2

Explanation

Output

2

Key Takeaways So Far

Types of Constructors in Python

The constructor method in python are utilised to initialise class objects. They are invoked through the __init__ method. There are two types of constructors in Python:

1. Default Constructor

A default constructor does not accept any argument except self. It initialises an object by passing no initial values for object attributes.

If a constructor is not defined in a class, Python also offers a default constructor that can utilize default values for initializing the object.

Example

class Person:
    def __init__(self):
        self.name = "Deepthi"
        self.age = 22

p = Person()
print(p.name)
print(p.age)

Explanation

Output

Deepthi
22

Non-parameterized Constructor

The non-parameterized constructor can also be stated as a default constructor since it does not have any parameters but self. It is useful when you're creating objects with default values of attributes.

Example

class Car:
    def __init__(self):
        self.make = "Toyota"
        self.model = "Corolla"

car1 = Car()  # Non-parameterized constructor is invoked
print(car1.make)  # Output: Toyota

Explanation

Output

Toyota

2. Parameterized Constructor

A parameterized constructor that takes one or more parameters to set the object with particular values when the object is created. This enables you to create an object with personalized attributes.

Example

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person2 = Person("Deepthi", 22)  # Parameterized constructor is called
print(person2.name)  # Output: Deepthi

Explanation

Output

Deepthi

Python Instance Methods

Instance methods act on an instance of the class and access or change its attributes. They always have self as their first parameter.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")

# Creating an object of Person
person1 = Person("Deepthi", 22)

# Calling the instance method
person1.greet()

Explanation

Output

Hello, my name is Deepthi and I am 22 years old.

Key Takeaways So Far

More Than One Constructor in a Class

The constructor cannot be overloaded in Python. You can define several __init__() instances within one class, and the last one will replace the previous ones. To achieve the effect of overloading the constructors, you may use default argument lists or class methods.

Example

class Student:
    def __init__(self):
        print("First Constructor")

    def __init__(self):
        print("Second Constructor")

# Creating an object
st = Student()

Explanation

Output

Second Constructor

Python Built-in Class Functions

Python allows some built-in functions to be used on class attributes. A few of them are:

Example

class Employee:
    def __init__(self, name, emp_id, salary):
        self.name = name
        self.emp_id = emp_id
        self.salary = salary

e = Employee("Deepthi", 102, 100000)
print(getattr(e, 'name'))

# Changing the value of 'salary'
setattr(e, "salary", 150000)
print(getattr(e, 'salary'))

# Checking if 'emp_id' attribute exists
print(hasattr(e, 'emp_id'))

# Deleting 'salary' attribute
delattr(e, 'salary')
try:
    print(e.salary)
except AttributeError as error:
    print(error)

Explanation

Output

Deepthi
150000
True
Error: 'Employee' object has no attribute 'salary'

Built-in Class Attributes

Built-in attributes of Python classes provide information about the class:

Example

class Employee:

    def __init__(self, name, emp_id, age):
        self.name = name
        self.emp_id = emp_id
        self.age = age

    def display_details(self):
        print(f"Name: {self.name}, Employee ID: {self.emp_id}, Age: {self.age}")

# Creating an employee object
e = Employee("Deepthi", 102, 22)

print(e.__doc__)

print(e.__dict__)

print(e.__module__)

Explanation

Output

None
{'name': 'Deepthi', 'emp_id': 102, 'age': 22}
__main__

Quick Recap

Use getattr, setattr, and hasattr for dynamic access. Built-in attributes provide meta-information for classes.

Differences Between __init__ and __new__ Methods

Here are the key differences for __init__ and __new__ methods:

__init__ __new__
__init__ is invoked when the object is being initialized. It is invoked after the object is already initialized. __new__ is tasked with creating a new object. It is invoked prior to __init__.
__init__ is invoked after object creation. __new__ is invoked prior to __init__ in order to construct the object.
__init__ has no return value (returns None implicitly). It modifies the object's state. __new__ is required to return a new object, typically by calling its parent class's __new__ method.
It modifies the object after the object has already been created. It has to create the object itself, and not modify the object.
__init__ takes self and additional parameters for initialization. __new__ takes cls (the class type) and typically returns an instance of the class (or subclass).
Used to set the initial state (attributes) of the object after it has been created. Used to control how objects are created, such as when overriding object creation for custom behaviour.

Advanced Constructor Usage

Besides the regular object creation with init(), Python offers sophisticated methods that lead to an advanced constructor usage. With these methods, it's possible to manage complicated situations e.g. inheritance from immutable built-in types, changing the process of object creation, and using design patterns such as singletons. Being skilled in these ideas makes your code cleaner, more modular, and gives you more freedom in your class design.

Subclassing Immutable Built-in Types

Immutable types (like int, float, str, and tuple) require that their values be set at creation, not after. To customize these types, override the new() method rather than init().

Example: Subclassing float with an extra attribute

class Distance(float):
    def __new__(cls, value, unit):
        obj = super().__new__(cls, value)
        obj.unit = unit
        return obj

# Creating an instance
d = Distance(10.5, "km")

# Accessing the values
print(d)       # Output: 10.5
print(d.unit)  # Output: km

Explanation:

Returning Instances of a Different Class

By customizing new(), you can return an instance of a different class, turning your class into a flexible factory or enforcing custom object creators.

Example: Factory-like object creation

class Cat:
    def __init__(self):
        self.type = "Cat"

class Dog:
    def __init__(self):
        self.type = "Dog"

import random

class Pet:
    def __new__(cls):
        return random.choice([Cat(), Dog()])

pet = Pet()
print(pet.type)  # Output: "Cat" or "Dog"

Explanation:

Implementing Singleton Classes

A singleton class ensures only one instance exists. This is achieved by controlling instance creation in new().

Example: Singleton pattern

class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# Testing the Singleton
a = Singleton()
b = Singleton()
print(a is b)  # Output: True

Explanation:

Constructor Overloading

Python is not capable of standard constructor overloading but you can imitate it by using default arguments or args and **kwargs in init(). In this way, the initialization parameters become flexible and both default constructors and parameterized constructors are supported.

Example: Flexible constructor

class Rectangle:
    def __init__(self, width, height=None):
        if height is None:
            self.width = self.height = width
        else:
            self.width = width
            self.height = height

# Creating instances
r1 = Rectangle(5)
r2 = Rectangle(4, 6)

# Printing dimensions
print(r1.width, r1.height)  # Output: 5 5
print(r2.width, r2.height)  # Output: 4 6

As a consequence of delving into such advanced constructor methods—using init() and new(), allowing modular code, and making custom object creators—you are able to manage complicated situations like subclassing immutable types, instance returning of a different class, and singleton class enforcement. These designs elevate the code readability and adaptability aspects, thus, your Python classes turn out to be more efficient and sustainable.

Understanding the self Parameter

In Python's object-oriented programming, the self parameter plays a crucial role in constructors and class methods. It acts as a reference to the object being created or manipulated, allowing you to access and customize instance variables for each object.

What is the self Parameter?

Why is self Important?

Example: Using self in a Parameterized Constructor

class Person:
    def __init__(self, name, age):
        self.name = name  # Attribute customization
        self.age = age

p = Person("Deepthi", 22)
print(p.name)  # Output: Deepthi
print(p.age)   # Output: 22

Explanation:

self vs. Class Methods

By understanding and correctly using the self parameter, you enable powerful attribute customization, proper object creation, and maintain the core principles of object-oriented programming such as abstraction and inheritance.

Bottom Line

The self is essential for instance-specific behavior. Advanced constructors enable singletons, factories, and subclassing immutable types.

Best Practices and Common Mistakes

Thinking through the use of constructors is one of the things that help writing Python code which can be maintained and understood easily. In short, while working with default constructors and custom initialization logic, you should follow the best practices presented below and also be aware of mistakes that you should not make.

Best Practices

Common Mistakes

  1. Overcomplicating Constructors: Placing too much logic or computation inside a constructor can make your code hard to follow and maintain. If a constructor is getting too complex, consider moving logic to separate methods
  2. Ignoring Naming Conventions: Using non-standard names or misspelling init can break object initialization and confuse readers of your code
  3. Unnecessary Overhead for Simple Classes: When you define explicit constructors for classes that don't need them, you basically add unnecessary code to your project. Use Python's default constructor for simple cases
  4. Inconsistent Initialization: Not initializing all that are needed attributes may result in the program behaving unpredictably and the bugs being difficult to locate
  5. Lack of Documentation: Not documenting constructor parameters or expected usage can make your classes difficult to use correctly, especially in collaborative projects

By following these best practices and avoiding common mistakes, you can write constructors that enhance code readability, maintainability, and consistency—while keeping overhead low, especially for simple classes.

Benefits and Drawbacks of Constructors

Constructors are the main tools involved in creating new objects in Python. Through a default constructor, a parameterized constructor, or a non-parameterized constructor, one can manage the way objects are set up and even guarantee that they are initially configured correctly. Still, while constructors offer a lot of positive features, they have some disadvantages as well, which should be taken into account in everyday programming.

Benefits

  1. Encapsulation of Initialization Logic: Constructors allow you to centralize and encapsulate the initialization logic for your classes. This ensures that all objects are created with the necessary attributes set, improving code readability and maintainability
  2. Attribute Validation: If attribute validation is put directly in the constructor, it will be possible to stop the creation of invalid objects. It is particularly valuable for parameterized constructors, in which you can verify that the parameters for the initialization satisfy the given requirements
  3. Consistent Object Creation Process: Constructors unify the method of creating objects, thus, lessening the risk of attributes that are missing or wrongly set. Such a consistency is very helpful in big codebases and team projects
  4. Inheritance Scenarios Support: In object-oriented programming, constructors help inheritance by enabling base and derived classes to have their own initialization logic. This keeps the hierarchies of objects clear and predictable
  5. Allowing Design Patterns: Constructors are necessary for the implementation of some design patterns, for instance, the singleton design pattern, where the creation of a class is controlled or limited

Drawbacks

  1. Code Complexity: When the initialization logic becomes more involved, constructors can turn into complicated and unreadable code fragments, especially if there is handling of multiple parameters or inheritance scenarios
  2. Overhead for Simple Classes: Just by defining explicit constructors, very simple classes may become subjected to unnecessary overhead, thus the code becomes more verbose than necessary
  3. Modifying Constructors May Lead to Risks: If the class is extensively used, changing the signature or logic of its constructor can cause code that is already broken, thus it is necessary to update the places where the class is instantiated
  4. Inheritance Scenarios Can Be Complex: It is a problem of complex inheritance hierarchies to ensure that not only all constructors are called correctly but also that the attributes are initialized in the right order

If you comprehend absolutely the pros and cons of constructors, for instance, how can encapsulation, attribute validation, and design patterns like singletons help, while the risks of code complexity and difficulties in inheritance scenarios being among the drawbacks, you will be able to make better decisions when it comes to class organization.

Quick Note

Constructors make the process of creating objects faster, they initiate the objects in a consistent way, and they are compatible with OOP principles, however, you should not complicate your class or create unnecessary overhead if it is a simple class.

Conclusion

In conclusion, constructors in Python are significant when it comes to object initialization and setting their default state. Constructors provide the advantages of default as well as parameterized initialization of object attributes. Knowing how a constructor works and how __new__ and __init__ are distinct will aid you in constructing more efficient and useful Python classes.

Why it Matters?

It is very important for one to understand constructors in Python since that is the way they guarantee that objects are properly brought to life with the right attributes, they abide by the basic principles of OOP such as encapsulation and abstraction, they allow inheritance and also enable the use of advanced design patterns like singletons or factory methods that in the end lead to the improvement of code reliability, readability, and maintainability.

Practical Advice for Learners

Frequently Asked Questions

What is a Python constructor?

A Python constructor is a special method that is automatically called when an object of a class is instantiated. A constructor is applied to initialize the object's attributes (variables). Python constructs are implemented by using the __init__() method.

Is __init__ a Python constructor?

Yes, __init__() is a Python constructor function. It gets invoked when a new object of a class is being instantiated. The __init__() function is used to set up the state and properties of the object. The __init__() function has self as its first argument (which is an instance of the class) and can have additional arguments to initialize the object with values.

What is __init__ in Python class?

The __init__() method is a special method (a dunder method, short for "double underscore") used as the constructor in Python. It is automatically invoked when an object of a class is instantiated. Its main task is to initialize the object's attributes with values or to execute any setup that the object might required.

Why __init__ in Python?

The __init__() function in Python is used to initialize objects with certain values at the time they are being created. Without __init__, the object would not be created in its desired state, and the class would use default values. The __init__() function has the possibility of creating more readable and flexible code.


Source: NxtWave - CCBP Blog

Original URL: https://www.ccbp.in/blog/articles/constructors-in-python