How To Use Python __new__ Method Example

In Python, the __new__ method is similar to the __init__ method, but if both exist, the method __new__ executes first. In the base class Object, __new__ is defined as a static method and needs to pass a parameter cls.  The parameter cls represents the class that needs to be instantiated, and this parameter is provided automatically by the python parser at instantiation time.

1. Python __init__ Method & __new__ Method Overview.

  1. In Python, init() method is responsible for instantiating the class instance.
  2. And before init() is called, new() method decides whether to use the init() method or not, because the new() method can call other class constructors or simply return other objects as instances of this class.
  3. So __new__ method has below characters.
  4. The __new__() method is called when the class is ready to instantiate itself.
  5. The __new__() method is always a static method of the class, even if no static method decorator is added.

2. How to use __new__ method example.

  1. Open a terminal and run command $ python3 to go to python interactive environment console.
    :~$ python3
    Python 3.7.1 (default, Dec 14 2018, 19:28:38) 
    [GCC 7.3.0] :: Anaconda, Inc. on linux
    Type "help", "copyright", "credits" or "license" for more information.
    
  2. First, define a class Employee, it has two instance variables name and salary.
    >>> class Employee(object):
    ...   
    ...     def __init__(self, name, salary):
    ...         self.name = name
    ...         self.salary = salary
    ...      
    ...     def __new__(cls, name, salary):
    ...         if 0 < salary < 10000:
    ...             return object.__new__(cls)
    ...         else:
    ...             return None
    ...   
    ...     def __str__(self):
    ...         return '{0}({1})'.format(self.__class__.__name__, self.__dict__)
    
  3. Now create two Employee instances and print out their string representation value.
    >>> emp_tom = Employee('Tom', 8000)
    >>> emp_tom
    <__main__.Employee object at 0x7f2c69811278>
    >>> print(emp_tom)
    Employee({'name': 'Tom', 'salary': 8000})
    >>> 
    >>> 
    >>> emp_richard = Employee('Richard', 20000)
    >>> print(emp_richard)
    None
    

3. Python 3 and python 2 use _new_ differently.

3.1 Use __new__ method in python 2.

  1. Please note that the method __new__ is only supported in python version 2.7 or greater.
    >>> class Employee(object):
    ...     def __new__(cls,*args, **kwargs):
    
    ...         if not hasattr(cls,'_inst'):
    
    ...             print(cls)
    
    ...             cls._inst = super(Employee, cls).__new__(cls,*args,**kwargs)
    
    ...         return cls._inst
    
    ... 
    
    >>> obj = Employee()
    
    <class '__main__.Employee'>
    
    >>> print(obj)
    
    <__main__.Employee object at 0x7f2c698113c8>
    

3.2 Use __new__ method in python 3.

  1. The below example shows how to use the __new__ method in python 3.
    class Employee(object):
    
        def __new__(cls,*args, **kwargs):
    
            if not hasattr(cls,'_inst'):
    
                print(cls)
    
                cls._inst = super(Employee, cls).__new__(cls)
    
                # if Python3 is written the same way as Python2 like below, it will throw error "TypeError: object() takes no parameters"
    
                # cls._inst = super(Employee, cls).__new__(cls, *args,**kwargs)
    
            return cls._inst

4. Question & Answer.

4.1 Why __new__() method run first and __init__() method run later when create a python object?

  1. I create a python class that has both __init__ method and __new__ method. Each time I create an instance of the class, I find the __new__ method always runs first and the __init__ method runs later, can you tell me why? Below is the source code.
    class MyClass(object):
        
        def __new__(cls):
            print("__new__")
            return object.__new__(cls)
    
        def __init__(self):
            print("__init__")
            
            
    if __name__ == '__main__':
         
         my_class = MyClass()
         
         my_class_1 = MyClass()    
    
    # Below is the above source code execution output.
    __new__
    __init__
    __new__
    __init__
    
  2. The reason for the __new__ method always runs before __init__ method is because the __new__ method is a class-level static method. When you create an instance of the class by invoking the class constructor, the class static __new__ method will be invoked first to create the class instance, then the instance will call the instance level __init__ method to initialize the python class instance. From your class definition, you can see that the __new__ method parameter is cls, and the __init__ mehtod parameter is self, the self parameter exists only after the instance has been created.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.