The difference between __new__ and __init__ is mainly focus on self distinction and new-style and old-style python class definition. This article will show their difference with examples.
1. Difference Between __new__ And __init__ Method.
- __new__ : Responsible for object creation, when __new__ method is called, it will return an instance of the current object.
- __init__ : Responsible for object initialization, __init__ method will be called after object creation, this method do not return value.
2. In A Python Class, If __new__ And __init__ All Exist Then __new__ Is Called First.
Below examples will be executed in Python interactive environment. So open a terminal and input $ python
or $ python3
in it. Then run below example code, you can see new is printed out.
:~$ 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. >>> class ClsTest: ... def __init__(self): ... print("init") ... def __new__(cls,*args, **kwargs): ... print("new") ... # you must run below code after above class definition ( after a new line with >>> ), otherwise you will get error like SyntaxError: invalid syntax >>> ct1 = ClsTest >>> ct1 <class '__main__.ClsTest'> >>> ClsTest() new
3. If __new__ Returns An Instance Of An Object, __init__ Is Implicitly Called.
>>> class ClsTest(object): ... def __init__(self): ... print ("init") ... def __new__(cls,*args, **kwargs): ... print ("new %s"%cls) # the __new__ method return an object, so __init__ method is called also. ... return object.__new__(cls, *args, **kwargs) ... ... >>> ClsTest() new <class '__main__.ClsTest'> init <__main__.ClsTest object at 0x7fb0c2e38cc0>
4. The __new__ Method Returns The Constructed Object, But __init__ Does Not. __init__ Has No Return Value.
>>> class ClsTest(object): ... def __init__(cls): ... cls.x = 2 ... print ("init") ... return cls ... >>> ClsTest <class '__main__.ClsTest'> >>> ClsTest() init Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() should return None, not 'ClsTest'
5. If __new__ Does Not Correctly Return An Instance Of Current Class, __init__ Will Not Be Called. Even If Parent Class Defined __init__ Method.
>>> class ClsTest1(object): ... pass ... # ClsTest2 __new__ method return ClsTest1 instance. >>> class ClsTest2(ClsTest1): ... def __init__(self): ... print ("init") ... def __new__(cls,*args, **kwargs): ... print ("new %s"%cls) ... return object.__new__(ClsTest1, *args, **kwargs) ... # so only __new__ method is invoked. >>> b=ClsTest2() new <class '__main__.ClsTest2'> >>> print (type(b)) <class '__main__.ClsTest1'> >>> # ClsTest3 __new__ method return ClsTest2 instance. >>> class ClsTest3(ClsTest1): ... def __init__(self): ... print ("init") ... def __new__(cls,*args, **kwargs): ... print ("new %s"%cls) ... return object.__new__(ClsTest3, *args, **kwargs) ... # both __new__, __init__ method are invoked. >>> c=ClsTest3() new <class '__main__.ClsTest3'> init >>>
6. Conclusion.
- Only new style python class that inherited from object has __new__ method.
- __new__ must have at least one parameter cls, cls represent the class to be instantiated. This parameter is provided automatically by the Python interpreter at instantiation time.
- __new__ must have a return value which is the instantiated instance. The instance can be parent class’s __new__ instance, or directly an instance of object’s __new__ instance.
- __init__ has a parameter self, which is the instance returned by this class’s __new__ method.
- __init__ can do some other initialization on top of __new__, and __init__ does not require a return value.
-
If __new__ returns an instance of an object, __init__ is implicitly called.