What is the difference between `__new__` and `__init__` in Python, and when would you override `__new__`?
`__new__` allocates and returns the new object; `__init__` receives that object and populates its attributes. You rarely touch `__new__` — its main legitimate uses are subclassing immutable types like `int` or `str`, and implementing the Singleton pattern.
How to think about it
What this is really testing
Most Python developers have never touched __new__. But the question reveals whether you understand when __init__ isn’t enough. The answer is narrow: immutable types (where the value is baked in at allocation, so __init__ is too late) and the Singleton pattern.
The two-step object creation protocol
The normal case: just use __init__
For mutable classes you will never need __new__. Python allocates the instance automatically through object.__new__, then calls your __init__ to set attributes.
When __new__ matters: immutable types
You cannot mutate an int inside __init__ because the integer’s value is baked in at allocation time. To create a clamped integer subtype you must intercept __new__:
__init__ must return None
If you accidentally return something from __init__, Python raises TypeError: __init__() should return None. In contrast, __new__ must return an object — if it doesn’t return an instance of cls, __init__ is skipped and the caller receives whatever __new__ returned.
The key insight
Think of object creation as a factory line: __new__ stamps out the blank part; __init__ fills in the details. For mutable objects the blank is already usable, so you only ever fill in __init__. For immutable objects the value is the blank — you have to get it right at the stamp.