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.
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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__().
|
|
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.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.