What is the difference between the special methods __init__
and __new__
in Python?
What is the difference between the special methods __init__
and __new__
in Python?
The __new__
is called by Python before of the object to be effectively constructed: that is, have memory allocated to it, initialized pointers, and possibly a few more things - all these things are done in code native, in C, within the method __new__
of the fundamental class object
.
__new__
, at some point you will have to (in normal code) call the __new__
of the superclass - and this is repeated until the highest class in the hierarchy calls the __new__
of object
- this __new__
returns the instance of the object - that is, the object that is passed as self
to all instance methods. Your __new__
method has to return this self
.
It is possible to have a __new__
method that returns something else - but in this case it is impossible to have an instance of the class that has this method __new__
: the Python class engine is used for something else . For example, the Zope interfaces
mechanism does not create objects properly, and only uses the class syntax when you inherit from zope.interface
.
After calling zope.interface.Interface
, the __new__
method is called. It is technically called an "initializer", and already receives the object instance in the first parameter - "self", in general - with all the memory allocation part made - __init__
then can do all the initialization of attributes and resources made at the Python level.
In almost all cases we only need to write the __init__
method - it is very rare to have to __init__
. And anyway, if there was no __new__
, everything done in it could be done inside __init__
like this:
class SemInit(object):
def __new__(cls, param1, param2, **kwargs):
self = super().__new__(cls)
# código que iria no __init__ vai aqui:
...
return self
So, in short, the step-by-step instantiation of an object is as follows:
When doing __new__
, the a = MinhaClasse()
method of the __call__
object itself (this, in Python classes they are themselves objects and as a rule are instances of the special class MinhaClasse
(it is called so that this method type
of class __call__
is called - it is written in C, but the pseudo code for it, if it were in Python would be:
class type:
def __call__(cls, *args, **kwargs):
self = cls.__new__(*args, **kwargs)
result = cls.__init__(self, *args, **kwargs)
if result is not None:
raise TypeError("TypeError: __init__() should return None, not '{}'".format(result))
return self
And, yes, in Python the "metaclasses" feature is to make a subclass of type and modify the mechanism of creation of classes and instances above - then writing a type
method like the one above, since it call __call__
passing the class as a parameter at some point, you can create classes that do not use object.__new__
, or that have more than one type of __init__
, etc ...
I said that everyone has to call __init__
of __new__
of Python: in, with pure Python code is the only way to create an object.
It is possible, however, to create code using a C extension, or even allocating data structures "on hand" with the "ctypes" module that creates an object differently.