O __new__ is called by Python before of the object to be effectively built: that is, having allocated memory for it, initialized hands, and possiblement some more things - all these things are done in the native code, in C, within the method __new__ of the fundamental class object.When you do an override __new__, at some point you will have to (in normal code) call the __new__ of superclass - and this repeats until the highest class in the hierarchy calls the __new__ of object - That __new__ returns the instance of the object - that is, the object that is passed as self for all instance methods. Your method __new__ must return this self.It is possible to have a method __new__ that returns something else - but in that case it is impossible to have an instance proper of the class that has this method __new__: the Python class mechanism is used for something else. For example, the mechanism of interfaces of the Zope (package) zope.interface) does not create objects properly said, and only uses class syntax when you inherit from zope.interface.Interface.After calling him __new__, the method __init__ is called. It is technically called "initiator", and already receives the instance of the object in the first parameter - "self", in general - with tod the part of memory lodge made - the __init__then you can do all the initialization of attributes and features made at the Python level. In almost all cases we just need to write the method __init__ - it's very rare that you need to move __new__. And anyway, if there was no __init__, all that is done in it could be done within __new__ in this way: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 of the instance of an object is as follows:when you do a = MinhaClasse(), the method __call__ of the object MinhaClasse- in itself (this, in Python classes are themselves objects and as a rule are instances of the special class type (it is called "metaclasse"). then, this method __call__ of class type 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 valid which consists of making a subclass of type and modifying the above class and instance creation mechanism - then writing a method __call__ as the above, provided he calls the object.__new__ passing the class as a paremeter at some point, you can create classes that do not use the __init__, or that has more than one type of __init__, etc...I said everyone has to call __new__ the object of Python: in, with pure Python code is the only way to create an object.It is possible, however, to create code using an extension in C, or even by allocating "in-hand" data structures with the "ctypes" module that creates an object differently.update: And when we must encode the __new__?When we're going to create a subclass of a "immutable" native Python data type, such as int or other number, str or tuple.
In such cases, if we want to change the value of the content, it is necessary to act in __new__ before calling it __new__ original. After that, the value is already configured and cannot be changed. For example, a sub-class of string that converts all content to uppercases already in creation could be:class StrUpper(str):
def __new__(cls, value):
value = value.upper()
return super().__new__(cls, value)
Note another feature when implementing __new__: time to call the method __new__ of the superclass, with super(), it is necessary to place the parameter cls explicitly in the arguments. For normal class methods and methods, the super() That's the part. O __new__ is a special method, on account of how language works - despite looking like a class method, internally it is a static method, and the cls is always added explicitly, not by language.In other words: we use __new__ only to intercept and change parameters in classes that consume these parameters already in creation. Besides the immutable types, it is common to write the __new__ when creating a metaclass - that will change some behavior in creating classes itself. Outside these cases, even inheriting from native types like dict and list, just use the __init__ Yeah.