← Back to Python

__new__ vs __init__

PythonSeniorpython

The Question

What is the difference between __new__ and __init__?

What a Strong Answer Covers

  • __new__ creates
  • cls
  • "__init__ initializes
  • self
  • "immutable types/singleton

Senior-Level Answer

Object creation in Python is a two-step process mediated by `__new__` and `__init__`.

`__new__(cls, *args, **kwargs)` is a static method (special-cased by Python) that is responsible for **allocating and returning a new instance**. It receives the class as its first argument and should return an instance of that class (or a different class, which bypasses `__init__`). `object.__new__(cls)` is the default implementation — it allocates memory for the new object.

`__init__(self, *args, **kwargs)` receives the **already-allocated instance** as `self` and is responsible for **initializing its state**. It must return `None`. It is called only if `__new__` returns an instance of `cls` (or a subclass).

The call sequence when you write `Foo(1, 2)`: 1. Python calls `Foo.__new__(Foo, 1, 2)` 2. If the result is an instance of `Foo`, Python calls `result.__init__(1, 2)` 3. The instance is returned to the caller

**When to override `__new__`:**

*Immutable type subclassing:* Immutable types like `int`, `str`, and `tuple` have their value baked in at allocation time. `__init__` is too late to change the value. To customize their construction, you must override `__new__`:

```python class PositiveInt(int): def __new__(cls, value): if value <= 0: raise ValueError('Must be positive') return super().__new__(cls, value) ```

*Singleton pattern:*

```python class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance ```

*Metaclasses and class creation:* Metaclasses override `__new__` to control how class objects themselves are created.

*Object deserialization:* `pickle` and `copy` can call `__new__` without `__init__` to reconstruct objects without re-running initialization logic.

**The critical rule:** If `__new__` returns an instance that is NOT an instance of `cls`, `__init__` is not called. This allows factory-like behavior where `__new__` returns different types based on arguments.

For regular mutable classes, override only `__init__`. Overriding `__new__` on a normal class is a code smell unless you have a specific reason.

Key Differences

Aspect__new____init__
PurposeAllocate and return instanceInitialize instance state
First argumentcls (the class)self (the instance)
Return valueNew instance (usually)Must return None
Called whenAlways on constructionOnly if __new__ returns cls instance
Required for immutable subclassingYesNo
Override frequencyRare (specific patterns)Common (almost always)

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly explains that __new__ allocates and returns the instance while __init__ initializes it, with the call order, and gives one valid use case for overriding __new__.

3/3 — Strong Answer

Covers allocation vs initialization distinction, explains the immutable type constraint, shows singleton pattern, knows that __init__ is skipped if __new__ returns a non-cls instance, and mentions pickle/copy interaction.

Common Mistakes

  • Saying __init__ 'creates' the object — it only initializes an already-created object
  • Not knowing why immutable types require __new__ override — confusing when each is 'too late'
  • Overriding __new__ on mutable classes where __init__ suffices
  • Not knowing that __new__ is technically a staticmethod, special-cased by the Python data model

Follow-Up Questions

  • Why can't you set the value of an int subclass in __init__? — int is immutable — its value is fixed at allocation. __init__ runs after the object is fully constructed. You must use __new__ to pass the value to int.__new__.
  • What happens if __new__ returns an instance of a completely different class? — __init__ is skipped entirely. Python only calls __init__ when __new__ returns an instance of cls or a subclass.
  • How does pickle use __new__? — By default, pickle calls __new__(cls) without arguments and then sets __dict__ directly, bypassing __init__. __reduce__ or __reduce_ex__ controls this.
  • How do metaclasses relate to __new__? — A metaclass is a class whose instances are classes. type.__new__(mcs, name, bases, namespace) creates the class object. Overriding this in a metaclass controls class creation.

Related Questions

  • GIL — What It Is and What It Protects
  • ThreadPoolExecutor & ProcessPoolExecutor
  • Decorators — Under the Hood
  • Generators & yield
  • Context Managers

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout