Phase 7 of 25 · Topic 7.1

Classes, Instances & __new__ vs __init__ Object Allocation

1Concept

`__new__()` is the static allocator method that creates and returns a new blank instance of the class. `__init__()` is the initializer method that configures the newly allocated instance. Singleton classes and immutable type subclasses must override `__new__()`.

2Architecture Diagram

Class Invocation: User("Alice")
       |
       v Step 1: __new__(cls) ---> Allocates memory & returns blank instance
       v Step 2: __init__(self, "Alice") ---> Initializes fields on instance

3Code Example

Python 3.12
class SingletonRegistry:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, env: str = "PROD"):
        self.env = env

s1 = SingletonRegistry("PROD")
s2 = SingletonRegistry("STAGING")

print(f"s1 is s2 (Same memory address): {s1 is s2}")
print(f"Active Environment: {s1.env}")

4Expected Output

s1 is s2 (Same memory address): True
Active Environment: STAGING

5Key Takeaways

  • `__new__` must return an instance of the class for `__init__` to be invoked.
  • Subclasses of immutable types (`int`, `str`, `tuple`) must modify values in `__new__`.
  • Use metaclasses or dependency injection containers for production-grade singletons.