__init__ and __new__

RoadmapsPython

Overview

When creating an object in Python, `__new__` is called first to allocate memory and return an uninitialized instance. `__init__` is then called on that instance to initialize its state. Most developers only use `__init__`. You only need `__new__` when you need to control the creation of a new instance. Common use cases include returning an existing instance for a Singleton, or subclassing immutable types like `tuple` or `str`. It is like building a house: `__new__` lays the foundation and frames the structure, while `__init__` paints the walls and moves the furniture in. class Sneaky: def __new__(cls): return 42 def __init__(self): print("Never runs!") obj = Sneaky() # obj is 42 If `__new__` returns something that is not an instance of `cls`, Python skips calling `__init__` entirely. This is a common trap when overriding object creation. class Singleton: _instance = None def __new__(cls): if not cls._instance: cls._instance = super().__new__(cls) return cls._instance def __init__(self): print("Init called!") a = Singleton() b = Singleton() # Prints "Init called!" again! Even if `__new__` returns an already-created instance, Python still automatically calls `__init__` on it every single time. This complicates initialization in some patterns, covered fully in `singleton-pattern`.

Understanding the two-step instantiation process allows you to implement advanced patterns like Singletons, flyweight objects, and custom metaclasses.

Where used: Django ORM model instantiation, Pydantic model creation, Standard library singletons

Why learn this

Code walkthrough

class Person:
    def __new__(cls, name):
        print('1. Creating instance')
        return super().__new__(cls)
    def __init__(self, name):
        print('2. Initializing instance')
        self.name = name

p = Person('Alice')

Focus: return super().__new__(cls)

Aha moment

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

a = Singleton()
b = Singleton()
print(a is b)

Prediction: What does this print?

Common guess: False

Because `__new__` intercepts the creation step, it can return an already-existing object. Here, it returns the same instance for both `a` and `b`, making `a is b` true.

Common mistakes

Glossary

Singleton
A design pattern that ensures a class only ever has one single instance created, no matter how many times you try to instantiate it. Example: `db1 = DB(); db2 = DB(); assert db1 is db2` — both variables point to the same object.
flyweight
A design pattern that minimizes memory usage by sharing as much data as possible with other similar objects. Example: Python reuses the same integer object for small numbers like `1` rather than creating a new object each time.

Recall questions

Understanding checks

What will this code print when executed?

new init

Python first calls `__new__` which allocates the instance and returns it, and since the instance returned is of type `Custom`, Python immediately calls `__init__`.

What will this code print when executed?

new

Because `__new__` does not explicitly return the newly created instance, it implicitly returns `None`. Since it didn't return an instance of `MissingReturn`, `__init__` is never called.

Practice tasks

Subclassing float

The provided code subclasses `float` but doesn't change its behavior. Modify it by overriding `__new__` so that any value passed to `PositiveFloat` is converted to its absolute value before initialization.

Challenge

Implementing a basic Singleton

Implement a `DatabaseConnection` class using the Singleton pattern. It should have an `__init__` method that sets `self.connected = True` ONLY if the connection hasn't been established yet. Overriding `__new__` will let you ensure only one instance is ever created.

Continue learning

Next: Singleton pattern

Return to Python Roadmap