Constructors in Python (init vs __new__)

<!DOCTYPE html>

Constructors in Python: init vs new

<br> body {<br> font-family: sans-serif;<br> margin: 0;<br> padding: 20px;<br> }</p>
<div class=”highlight”><pre class=”highlight plaintext”><code>h1, h2, h3 { margin-top: 30px;
} pre { background-color: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto;
} code { font-family: monospace;
} img { max-width: 100%; display: block; margin: 20px auto;
}
</code></pre></div>
<p>


Constructors in Python: init vs new

In the realm of object-oriented programming (OOP), constructors play a pivotal role in initializing objects. Python, a versatile OOP language, provides two special methods for this purpose:

init

and

new

. While they both seem to serve the same purpose at first glance, they differ significantly in their functionalities and use cases. This article delves into the intricacies of these methods, unraveling their roles and demonstrating their distinct applications.


Understanding Constructors in Python

Constructors are special methods invoked automatically when a new object of a class is created. They act as blueprints for setting up the initial state of an object, defining its attributes and providing default values. In Python, the primary constructor method is

init

, which is responsible for initializing an object’s attributes after it has been created.


The Role of init

The

init

method is the cornerstone of object initialization in Python. It receives the object itself as the first argument (conventionally referred to as

self

), followed by any additional parameters you want to pass during object creation. The

init

method’s key role is to assign values to an object’s attributes.

Here’s a simple illustration:

class Car: def __init__(self, brand, model, year): self.brand = brand self.model = model self.year = year my_car = Car("Toyota", "Camry", 2023)
print(my_car.brand) # Output: Toyota

In this example, the

init

method assigns the values passed during object creation (“Toyota”, “Camry”, 2023) to the

brand

,

model

, and

year

attributes of the

my_car

object.


The Role of new

The

new

method, often overlooked, operates at a lower level than

init

. It’s responsible for creating the actual object instance before

init

is called.

new

takes the class itself (

cls

) as its first argument and any additional arguments you want to pass to it.

The primary purpose of

new

is to control the object’s creation process, particularly when you need to customize how objects are instantiated. It allows you to:

  • Return an instance of a different class, effectively creating a proxy object.
  • Create objects with specific constraints or conditions.
  • Modify the behavior of object creation for subclasses.


Key Differences: init vs new

The table below highlights the key distinctions between

init

and

new

:

| Feature | init | new |
|—|—|—|
| Purpose | Initializes an object’s attributes | Creates the object instance |
| When called | After object creation | Before object creation |
| First argument |

self

(object instance) |

cls

(class itself) |
| Returns | None | Object instance |
| Responsibility | Assigns values to attributes | Controls object creation |


Illustrative Examples


Example 1: Overriding new for Singleton Pattern

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. We can implement this using

new

to control object creation.

class Singleton: _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self, data): self.data = data s1 = Singleton("First instance")
s2 = Singleton("Second instance")
print(s1 is s2) # Output: True
print(s1.data) # Output: First instance

In this example,

new

checks if an instance already exists. If not, it creates a new one. Otherwise, it returns the existing instance. This guarantees that only one instance of the

Singleton

class can be created.


Example 2: new with Class Inheritance

class Animal: def __init__(self, name): self.name = name class Dog(Animal): def __new__(cls, *args, **kwargs): if "breed" in kwargs: return super(Dog, cls).__new__(cls, *args, **kwargs) else: raise ValueError("Dog breed is required") def __init__(self, name, breed): super().__init__(name) self.breed = breed my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # Output: Buddy
print(my_dog.breed) # Output: Golden Retriever

try: another_dog = Dog("Max")
except ValueError as e: print(e) # Output: Dog breed is required

Here, the

new

method in the

Dog

class checks if a breed is provided during object creation. If not, it raises a ValueError. This ensures that Dog objects are created only when the breed is specified.

Use Cases for init vs new

The choice between

init

and

new

depends on the specific scenario and the level of control you require over object creation:

When to use init:

  • To initialize attributes of an object after it has been created.
  • When you need to set up the object’s internal state or perform basic initialization tasks.
  • For standard object creation scenarios where no customization is required.

When to use new:

  • To control the object creation process, including the object’s type.
  • To implement design patterns like Singleton or Factory methods.
  • When you want to introduce constraints or checks on object creation.
  • When subclassing and needing to modify the object creation process.

Conclusion

The

init

and

new

methods are essential components of object-oriented programming in Python. Understanding their roles and differences is crucial for writing robust and well-structured code. While

init

is the primary method for initializing objects,

new

provides a powerful mechanism to customize object creation for more complex scenarios. Choosing the right method depends on the specific requirements of your program and the desired level of control over the object instantiation process.


Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top