Difference Between __init__() and __new__() in Python
In Python, both __init__() and __new__() are special methods related to object creation, but they serve different purposes in the object lifecycle.
__new__():
- Purpose: The
__new__()method is responsible for creating a new instance of a class. It is called before__init__()and is used to actually create the object in memory. - Usage: This method is primarily used in metaclasses or when you need to customize object creation. In most cases, you don’t need to override it unless you are dealing with special cases (e.g., singletons, immutable objects).
- Return Value:
__new__()must return the newly created object (an instance of the class). - When It’s Called:
__new__()is called before__init__()and can be thought of as creating the object, while__init__()is used to initialize it.
__init__():
- Purpose: The
__init__()method is responsible for initializing the newly created object. It’s called immediately after__new__()and is used to set up the object’s initial state. - Usage: This method is typically overridden in most classes to initialize attributes.
- Return Value:
__init__()does not return a value; it should always returnNone. - When It’s Called:
__init__()is called after__new__()has created the object and is used to initialize it.
Key Differences:
| Aspect | __new__() |
__init__() |
|---|---|---|
| Purpose | Creates a new object | Initializes the newly created object |
| Return Value | Returns the new object (instance) | Returns None |
| When Called | Called before __init__() |
Called after __new__() |
| Use Cases | Customizing object creation (e.g., singletons, immutable types) | Initializing object attributes |
Example:
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating a new instance")
instance = super().__new__(cls) # Create the instance
return instance
def __init__(self, name):
print("Initializing the instance")
self.name = name
# Create an instance
obj = MyClass("John")
Output:
Creating a new instance
Initializing the instance
__new__()is responsible for creating the instance, and__init__()initializes it.
When to Use Each:
- Override
__new__()when you need control over object creation, such as when implementing design patterns like the Singleton pattern. - Override
__init__()when you need to initialize the attributes of an object after it has been created.
In most cases, __init__() is the method you’ll need to work with, and __new__() is used in more advanced or specialized use cases.
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating a new instance")
instance = super().__new__(cls) # Create the instance
return instance
def __init__(self, name):
print("Initializing the instance")
self.name = name
# Create an instance
obj = MyClass("John")
Interview angle
- “
__new__versus__init__?” -__new__creates and returns the instance;__init__initialises the one already created.__new__is a static method receiving the class,__init__receives the instance. - “When do you override
__new__?” - subclassing immutable types liketupleorstr, implementing a singleton or instance cache, or returning an object of a different class. Rare in application code. - “What’s the trap?” - if
__new__returns something that isn’t an instance of the class,__init__is never called. That silent skip is the bug people hit.