Python __new__: Control Object Creation Before __init__

Quick answer: Python calls __new__ to create or return an instance before __init__ initializes it. Override __new__ mainly for immutable subclasses, controlled instance reuse, or allocation decisions; otherwise ordinary __init__ construction is usually clearer.

Python Pool infographic showing __new__ creating an instance before __init__ initializes its attributes in the object construction lifecycle
Python calls __new__ to create or return an instance before __init__ initializes it; immutable types often need values set in __new__.

__new__() is the Python data model method that creates a new object. It runs before __init__(). Most classes do not need to define it, because the inherited implementation from object already creates a normal instance.

The difference between __new__() and __init__() is simple but important. __new__() allocates and returns the object. __init__() receives that object and fills in starting state. If __new__() does not return an instance of the class, Python may skip that class’s __init__().

The official Python data model documents object.__new__() and object.__init__(). The Python tutorial on classes gives broader object-oriented background, and the super() reference explains cooperative parent calls.

Use __new__() only when object creation itself needs control. Common examples include immutable type subclasses, controlled caching, singleton-style objects, and advanced frameworks. For ordinary setup, prefer __init__() because it is easier to read and less surprising.

A correct __new__() method is usually a @staticmethod-like class method in practice: it receives cls, calls super().__new__(cls) or the parent type’s __new__(), and returns the created object. The examples below keep that flow explicit.

When reading code that defines __new__(), ask two questions. First, does the method always return the kind of object callers expect? Second, can __init__() still run safely after that return? Those questions catch most surprising bugs around caches, immutable values, and alternate object creation paths.

Also remember that __new__() is inherited. If a subclass overrides it, parent class behavior may still matter through super(). Keep the method small and document the reason it exists, because future maintainers will naturally look for normal setup code in __init__().

See The Creation Order

This example prints from both methods so you can see that __new__() runs first.

class Item:
    def __new__(cls, name):
        print("__new__ creates the object")
        obj = super().__new__(cls)
        return obj

    def __init__(self, name):
        print("__init__ sets the state")
        self.name = name

item = Item("book")
print(item.name)

The object returned by __new__() becomes self inside __init__(). That is why __init__() can set attributes on the object but does not create it from scratch.

For normal classes, this custom __new__() method is unnecessary. It is shown here only to make the call order visible.

If this example looks too verbose for ordinary class setup, that is the point. Most application classes should not spell out object allocation.

Create An Immutable str Subclass

Immutable built-in types such as str, tuple, and int need their value during creation. That makes __new__() the right place to normalize the stored value.

class Slug(str):
    def __new__(cls, text):
        cleaned = text.strip().lower().replace(" ", "-")
        return super().__new__(cls, cleaned)

slug = Slug(" Python New Method ")

print(slug)
print(isinstance(slug, str))

The string value is already fixed by the time __init__() would run. Using __new__() lets the subclass choose the final text before the immutable string object exists.

This pattern is useful for small value types, but it should stay simple. Heavy parsing or I/O inside __new__() makes object creation harder to reason about.

If normalization might fail with a detailed validation message, a separate factory function can be clearer than putting every rule inside the allocation step.

Python Pool infographic showing class call, __new__, object allocation, and instance creation
Object call: Class call, __new__, object allocation, and instance creation.

Add Attributes After Creation

__new__() creates the object, while __init__() can still add ordinary attributes when the type allows them.

class Product:
    def __new__(cls, name, price):
        obj = super().__new__(cls)
        return obj

    def __init__(self, name, price):
        self.name = name
        self.price = price

product = Product("keyboard", 50)

print(product.name)
print(product.price)

This split is rarely needed for normal mutable classes, but it shows the division of responsibility. Creation happens first, setup follows second.

If all you need is attributes such as name and price, write only __init__() and let Python inherit the standard creation behavior.

Reuse An Object From A Cache

__new__() can return an existing object. This is one reason caching and singleton patterns are usually implemented there instead of in __init__().

class SmallCode:
    _cache = {}

    def __new__(cls, code):
        if code not in cls._cache:
            obj = super().__new__(cls)
            obj.code = code
            cls._cache = obj
        return cls._cache

first = SmallCode("A1")
second = SmallCode("A1")

print(first is second)
print(first.code)

The two calls return the same object because the code already exists in the cache. This can be useful for tiny immutable-like value objects.

Be careful with cached mutable objects. If one part of the program changes a shared object, every caller that receives the same cached object sees that change.

Return A Different Class Carefully

If __new__() returns an object that is not an instance of the class being called, Python does not run that class's __init__().

class TextOrNumber:
    def __new__(cls, value):
        if isinstance(value, int):
            return value
        return str(value)

result_one = TextOrNumber(7)
result_two = TextOrNumber("seven")

print(result_one, type(result_one).__name__)
print(result_two, type(result_two).__name__)

This behavior is powerful but easy to overuse. In most application code, a named factory function or @classmethod constructor is clearer than a class call that returns an unexpected type.

Use this style only when the class's public contract clearly says object creation may return an existing or different object.

Unexpected return types can confuse type checkers, tests, and readers. Prefer explicit factory names when the result may not be an instance of the class being called.

Python Pool infographic mapping __new__ to an instance and __init__ to initialization
__new__ then __init__: __new__ to an instance and __init__ to initialization.

Prefer __init__ For Normal Setup

The safest rule is to avoid __new__() unless creation itself must change. Normal validation and attribute setup belong in __init__().

class User:
    def __init__(self, username):
        if not username:
            raise ValueError("username is required")
        self.username = username

user = User("pythonpool")

print(user.username)

This version is easier to test, inherit, and explain. It uses Python's normal object creation path and puts validation where most readers expect it.

In short, reach for __new__() when you need to control the object that gets returned, especially for immutable subclasses or caches. Use __init__() for ordinary setup, and prefer named factory methods when alternate construction would be clearer than customizing object allocation.

Follow The Construction Order

The class call invokes __new__ first. If it returns an instance of the class, Python then calls __init__ on that instance; if it returns another type, initialization rules change.

Python Pool infographic comparing subclass __new__, immutable types, caching, and returned instances
Subclass control: Subclass __new__, immutable types, caching, and returned instances.

Handle Immutable Values Early

Subclasses of int, str, tuple, and similar immutable types must establish their value during __new__. __init__ can configure attributes but cannot replace the already-created immutable value.

Keep Cooperative Inheritance

Use super().__new__ with the expected arguments when participating in a class hierarchy. Mismatched signatures or skipped base construction can break mixins and multiple inheritance.

Avoid Accidental Singleton State

Returning a cached instance from __new__ changes identity and can make state leak between callers. If reuse is required, document lifecycle, thread safety, and initialization behavior explicitly.

Python Pool infographic testing signatures, None, singleton patterns, inheritance, and validation
Construction checks: Signatures, None, singleton patterns, inheritance, and validation.

Separate Allocation From Validation

Validate arguments before expensive work where possible, but keep object creation and initialization responsibilities understandable. A factory function may be clearer than a complex __new__ override.

Test Identity And Initialization

Test subclass construction, immutable values, repeated calls, failed validation, inheritance, pickling when relevant, and whether __init__ runs exactly when expected. Assert identity separately from equality.

Use the official Python data model documentation for __new__. Related Python Pool references include tests and object configuration.

For related object design, compare construction tests, attribute state, and immutable sequence types before overriding __new__.

Frequently Asked Questions

What is the difference between __new__ and __init__?

__new__ creates or returns the instance, while __init__ initializes an instance that already exists; __new__ runs first.

When should I override __new__?

Use it for immutable subclasses, metaclass or allocation concerns, carefully controlled instance reuse, or a construction contract that must choose the instance.

Why is __new__ useful for immutable types?

An immutable value must be established during creation, before later initialization can assign attributes, so subclasses such as int or tuple may use __new__.

Can __new__ return another object?

Yes, but if it returns an instance of a different type, Python may skip __init__ for the original class; this behavior should be documented and tested.

Subscribe
Notify of
guest
3 Comments
Oldest
Newest Most Voted
Andrii
Andrii
5 years ago

If you started learning Python recently, find and read this article “The Inside Story on New-Style Classes”, it gives some real-world examples about the __new__ method.

Regarding the article, man you must have been in a hurry, please read what you’ve posted carefully; check PEP8 (class naming convention); inheritance from the object, and if you still want to inherit from object, at least don’t call super, call __new__ method directly: return object.__new__(cls)

Andreas Maier
Andreas Maier
3 years ago

On “From python 2.6, the developers have removed the extra arguments from object.__new__ method”:

That is not true. In the documentation of Python 2.7, 3.5 and higher, the object.__new__ method does have arbitrary parameters after the initial “cls” parameter: https://docs.python.org/3.10/reference/datamodel.html?highlight=__new__#object.__new__

Pratik Kinage
Admin
3 years ago
Reply to  Andreas Maier

Correct. Sorry for the incorrect phrasing of the statement. It was supposed to be ignored the extra arguments.