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.
- In Python,
init()
method is responsible for instantiating the class instance. - And before
init()
is called,new()
method decides whether to use theinit()
method or not, because thenew()
method can call other class constructors or simply return other objects as instances of this class. - So
__new__
method has below characters. - The
__new__()
method is called when the class is ready to instantiate itself. - 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.
- 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.
- 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__)
- 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.
- 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.
- 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?
- 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__
- 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 iscls
, and the__init__
mehtod parameter isself
, theself
parameter exists only after the instance has been created.