Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Python __new__ and Object Creation

Understand how class calls create instances through __new__ before __init__, and learn why __new__ is especially useful for immutable-type subclasses.

Levels: Advanced ~22 min read

Advanced

When you call a class, Python has to create an instance before that instance can be initialized. __new__() handles the creation step, while __init__() normally handles the initialization step that follows.

See the creation and initialization order

For a normal instance construction, Python first calls __new__() with the class as cls. If it returns an instance of that class, Python then calls __init__() on that instance. The completed object is then returned to the caller.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Report:
    def __new__(cls, name):
        print("__new__", name)
        instance = super().__new__(cls)
        return instance

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

report = Report("monthly")
print(report.name)

The creation hook runs before initialization. Both methods receive the constructor arguments, but they have different jobs.

Quick check

Which method is responsible for creating the new instance in the normal object-construction sequence?

class Record:
    def __new__(cls):
        print("new")
        return super().__new__(cls)

    def __init__(self):
        print("init")

Record()

Define __new__ with cls

The first parameter of __new__() is the class being constructed, conventionally named cls. Python treats __new__() as a static method for lookup purposes, so you do not write @staticmethod when defining it this way.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class User:
    def __new__(cls, name):
        instance = super().__new__(cls)
        return instance

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

user = User("Mina")
print(user.name)

The usual mutable-object pattern is to ask the parent class to create the instance and return that instance.

Let __init__ initialize the created object

The two methods cooperate but should not be treated as interchangeable. __new__() must return the object that the constructor call should use. __init__() receives that object afterward and normally assigns or validates its mutable state. Returning a non- None value from __init__() is invalid.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class User:
    def __new__(cls, name):
        print("create")
        return super().__new__(cls)

    def __init__(self, name):
        print("initialize")
        self.name = name.upper()

user = User("Mina")
print(user.name)

Use __new__ to obtain the instance and __init__ to configure the resulting mutable object.

Use __new__ when an immutable value must be chosen

Immutable built-in types such as str, int, and tuple cannot have their underlying value changed after creation. For a subclass of one of these types, __new__() is the place to compute the value before the immutable object exists.

python
1
2
3
4
5
6
7
class CleanText(str):
    def __new__(cls, value):
        cleaned = value.strip().lower()
        return super().__new__(cls, cleaned)

text = CleanText("  Ready  ")
print(text)

The string value is fixed during creation, so normalization belongs in __new__().

Quick check

Why is __new__() especially useful when subclassing an immutable built-in type?

class CleanText(str):
    def __new__(cls, value):
        cleaned = value.strip()
        return super().__new__(cls, cleaned)

CleanText(" ready ")

Return a subclass-aware instance

Use cls rather than hard-coding the base class when calling the parent implementation. That preserves the class actually being constructed and lets subclasses inherit the creation behavior correctly.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Code(str):
    def __new__(cls, value):
        value = value.strip()
        return super().__new__(cls, value)

class ShortCode(Code):
    pass

code = ShortCode("  A7  ")
print(code)
print(type(code).__name__)

Passing cls to the parent constructor preserves the subclass type when ShortCode is instantiated.

Know what happens when __new__ returns another type

The normal sequence has an important boundary: if __new__() returns an object that is not an instance of cls, Python does not call that class’s __init__() for the result. The class call simply produces the object returned by __new__().

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Token:
    def __new__(cls, value):
        return str(value)

    def __init__(self, value):
        raise RuntimeError("Token.__init__ should not run")

result = Token(42)
print(result)
print(type(result).__name__)

Because __new__ returns a str rather than a Token instance, Token.__init__() is skipped.

Quick check

What happens when __new__() returns an object that is not an instance of cls?

class Token:
    def __new__(cls, value):
        return str(value)

Token(42)

Keep metaclass creation separate

This lesson is about __new__() for creating ordinary instances. Python also uses __new__() in custom metaclasses to customize class creation, but that is a different data-model layer and belongs with metaclasses rather than with ordinary instance construction.

Quick check

Which pair best describes the normal instance-construction sequence?

class Item:
    def __new__(cls):
        print("new")
        return super().__new__(cls)

    def __init__(self):
        print("init")

Item()

Key takeaways

  • __new__() is the creation step for an instance, while __init__() normally initializes the instance returned by it.
  • The conventional first parameter of __new__() is cls, the class whose instance is being requested.
  • Subclassing immutable built-ins is a principal use of __new__() because the immutable value must be chosen during creation.
  • Calling super().__new__(cls, ...) preserves normal parent creation behavior and keeps the operation subclass-aware.
  • If __new__() returns an object that is not an instance of cls, cls.__init__() is not called for that returned object.
Was this page helpful?

Mark this learning resource complete to track your learning progress.