Detailed explanation of Python__ new__() method

The new () method mainly exists in the new class of Python 2 and in Python 3. It is the static method responsible for creating class instances.

When Python instantiates an object, it first calls the__ new__() Method to construct an instance of a class and allocate the memory space of the corresponding type for it. The memory address of the instance is its unique identifier. And then call__ init__() Method to initialize an instance, usually the properties of the instance.

Here are some examples to illustrate:

Example 1: call first__ new__() Method call again__ init__() method

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        return super().__new__(cls)
    
    def __init__(self):
        print("__init__ called")
		  
a = Person()
		

result:

__new__ called
__init__ called

Example 2: the new () method constructs a class instance and passes it to its own__ init__() Method, i.e__ init__() The self parameter of the method.

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        instance = super().__new__(cls)
        print(type(instance))
        print(instance)
        print(id(instance))
        return instance
    
    def __init__(self):
        print("__init__ called")
        print(id(self))

b = Person()

result:

__new__ called
<class '__main__.Person'>
<__main__.Person object at 0x1093c1580>
4449899904
__init__ called
4449899904

Example 3: if__ new__() Method does not return any instances, the init () method will not be called.

class Person(object):
    
    def __new__(cls):
        print("__new__ called")

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

c = Person()

result:

__new__ called

Example 4: if__ new__() Method returns an instance of another class__ init__() Method will not be called. Moreover, the new () method will initialize an object of another class.

class Animal(object):

    def __init__(self):
        pass

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        return Animal()

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

d = Person()
print(type(d))
print(d)

result:

__new__ called
<class '__main__.Animal'>
<__main__.Animal object at 0x10fea3550>

Example 5: if overridden__ new__() Method, except for the CLS parameter, if no other parameters are set, it cannot be used__ init__() Method to set initialization parameters.

class Person(object):
    
    def __new__(cls):
        print("__new__ called")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("__init__ called")
        self.name = name

e = Person("Eric")
print(e.name)

result:

Traceback (most recent call last):
  File "example.py", line 102, in <module>
    e = Person("Eric")
TypeError: __new__() takes 1 positional argument but 2 were given

Example 6: in rewriting__ new__() Method, you need to add * args, * * kwargs to the parameters, or explicitly add the corresponding parameters to pass__ init__() Method initialization parameters.

class Person(object):
    
    def __new__(cls, *args,**kwargs):  # Or def __new__(cls, name)
        print("__new__ called")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("__init__ called")
        self.name = name

e = Person("Eric")
print(e.name)

result:

__new__ called
__init__ called
Eric

Read More: