Python __new__ Explained With Examples

__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.

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.

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.

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.