The __new__()
static method gets called as the first method when an instance of a class is being created. It is responsible for allocating memory for the new object as well as for invoking the __init__()
method of the involved class after the object has been successfully created.
The method always takes the class whose instance is to be created as the first argument. The class is used as the blueprint for creating the new instance and for making some internal decisions like how much memory to allocate for the object. It also takes additional arguments for customizing the instance creation, which are passed by the class's constructor. The constructor is afterwards called again with the same arguments after the instance has been created for further setting up the object's initial state.
Any class in Python have this method defined by default. For example consider the following low-level way of instantiating various builtin data types
L = list.__new__(list)
print(L)
S = set.__new__(set)
print(S)
D = dict.__new__(dict)
print(D)
Overriding the __new__() method for custom classes
Method overriding involves making a new version of the method in the subclass that has the same name and signature as the method in the superclass. The code inside the subclass’s version replaces the code in the superclass’s version. This allows for the subclass to specialize the behavior of the method, making it more specific to the needs of the subclass.
By default the __new__() method simply creates a new instance of a given class, but it can be overridden to customize the instance creation process.
class MyClass:
def __new__(cls, *args, **kwargs):
new_obj = super().__new__(cls, *args, **kwargs) # Always remember to initialize the superclases' __new__() method.
#Custom code goes here
return new_obj
#We will never have more than 5 active users.
class User(object):
active_users = 0
def __new__(cls):
if User.active_users < 5:
instance = super().__new__(cls)
print("user created")
User.active_users += 1
return instance
else:
raise ValueError("Cannot have more than 5 active users.")
user1 = User()
user2 = User()
user3 = User()
user4 = User()
user5 = User()
# Throws ValueError
user6 = User()