__new__ is a special method that is responsible for creating a new instance of a class. It is automatically called before __init__ whenever an object is created. When an object is instantiated, Python follows this sequence:
- __new__: Creates and returns a new object.
- __init__: Initializes the newly created object.
Unlike __init__, which only initializes an existing object, __new__ actually creates the object and must return it.
Example: In this example, __new__ is called first to create the object, followed by __init__ to initialize it.
class A:
def __new__(cls):
print("Creating instance")
return super().__new__(cls)
def __init__(self):
print("Initializing instance")
A()
Output
Creating instance Initializing instance
Explanation:
- __new__(cls) is called first when A() is executed.
- super().__new__(cls) creates and returns a new instance of the class.
- After the object is created, __init__() is automatically called to initialize it.
Syntax
class ClassName:
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
Parameters:
- cls: The class whose instance is being created.
- *args, **kwargs (optional): Arguments passed during object creation.
Return Value: Returns a newly created instance of the class (or another object).
Examples
Example 1: In this example, __new__ does not return a new object. Since object creation fails, __init__ is never executed.
class A:
def __new__(cls):
print("Creating instance")
def __init__(self):
print("Initializing instance")
print(A())
Output
Creating instance None
Explanation:
- __new__() is called first and prints "Creating instance".
- Since it does not explicitly return an object, it returns None.
- Because no instance is created, __init__() is never called.
Example 2: In this example, __new__ returns a string instead of an instance of the class.
class A:
def __new__(cls):
print("Creating instance")
return "Hello, World!"
print(A())
Output
Creating instance Hello, World!
Explanation:
- __new__() returns the string "Hello, World!" instead of an instance of A.
- Since an instance of A is not created, __init__() is skipped.
- The returned string is printed directly.
Example 3: In this example, __new__ creates and returns an object of another class.
class Animal:
def __str__(self):
return "Animal Object"
class Person:
def __new__(cls):
return Animal()
def __init__(self):
print("Inside __init__")
print(Person())
Output
Animal Object
Explanation :
- Person.__new__() returns an instance of Animal.
- Since the returned object is not an instance of Person, Person.__init__() is never executed.
- print(Person()) calls Animal.__str__().
Example 4: This example shows that __new__ can return an object, while __init__ must always return None.
class A:
def __new__(cls):
print("Creating instance")
return "GeeksforGeeks"
class B:
def __init__(self):
print("Initializing instance")
return "GeeksforGeeks"
print(A())
print(B())
Output
Creating instance
GeeksforGeeks
Initializing instance
ERROR!
Traceback (most recent call last):
File "<main.py>", line 12, in <module>
TypeError: __init__() should return None, not 'str'
Explanation:
- A.__new__() returns a string, so "GeeksforGeeks" is printed successfully.
- B.__init__() incorrectly returns a string.
- Since __init__() must always return None, Python raises a TypeError.
When to use __new__
__new__ is rarely overridden, but it is useful in specific scenarios, such as:
- Implementing Singleton Pattern: Ensures only one instance of a class exists.
- Returning Cached Objects: Helps in memory optimization by reusing existing objects instead of creating new ones.
- Immutable Object Creation: Used in classes like str and tuple since they are immutable.
- Subclassing Immutable Types: When extending built-in immutable types like int, float or str.