If you have a class Foo then:
Foo()is the constructorFoo.__init__()is the initializerFoo.__new__()is the allocator
Construction of a Python object is simply allocation of a new instance followed by initialization of said instance.
Answer from Ignacio Vazquez-Abrams on Stack OverflowEssentially the title. I'm confused as to which of the above __init__ falls under, but I keep finding conflicting information when I try to research it .
If you have a class Foo then:
Foo()is the constructorFoo.__init__()is the initializerFoo.__new__()is the allocator
Construction of a Python object is simply allocation of a new instance followed by initialization of said instance.
Personally, I find "__init__ is not a constructor" to be pretty fine hair-splitting.
__init__ is called when a new object is requested. It is supposed to use its arguments to assign attributes on the new object, such that the required invariants for normal operation of the object are set up. The object is already a valid pre-existing place to store attributes by the time the code in __init__ begins running. The new object normally has no attributes defined on it already when the code in __init__ begins running (other than the ones that all objects possess).
A C++ constructor is called when a new object is requested. It is supposed to use its arguments to assign to fields on the new object, such that the required invariants for normal operation of the object are set up. The object is already a valid pre-existing place to store fields by the time the code in the constructor begins running. The new object has all its declared fields already when the code in the constructor begins running, but they contain garbage.
A Java constructor is called when a new object is requested. It is supposed to use its arguments to assign to fields on the new object, such that the required invariants for normal operation of the object are set up. The object is already a valid pre-existing place to store fields by the time the code in the constructor begins running. The new object has all its declared fields already when the code in the constructor begins running, with their default values.
The major difference between an __init__ method and a C++/Java constructor is in that last sentence I've highlighted, and that's just the difference between the static nature of Java/C++ and the dynamic nature of Python. I don't think this warrants calling them fundamentally different concepts that must not be referred to by the same word.
I think the main reason Pythonistas don't like to refer to __init__ as a constructor is that people think of C++/Java constructors as "making a new object", because that's what they seem to do when you call them. But there's really two things going on when you call a constructor; a new object is created and then the constructor is called to initialise it. In C++/Java the "create a new object" part of that is invisible, whereas that can be exposed/customised in Python (via the __new__ method).
So while the role of the __init__ method is extremely similar to the role of a C++/Java constructor, some people prefer to emphasise the fact that this isn't the whole process by saying that "__init__ is not a constructor".
python - Initializer vs Constructor - Stack Overflow
What is the difference between __init__ and __new__?
Ok, this is a FAQ but a good one. When you know this one, you know how python instantiates objects at the python level.
So here is the thing. When __init__ executes, you get a first parameter that is the instance of your class. Normally, this first parameter is called self. Inside init you do all you want on this empty instance, normally set member vars.
However, that instance has been created somehow. Who creates it?
here is where __new__ enters the game. __new__ is a class method, that is, when executed, it gets passed the class. The objective of new is to create the instance that will then emerge as self into __init__.
What is the default implementation of __new__? Generally, for a simple class (e.g. has no parents) it just calls object.__new__, something that creates a new instance of your class, but you can override it and do something before or after that. Technically, you could only use __new__, put all the stuff you have in __init__ just after the call to object.__new__() and be done with it. In practice, you prefer init because you don't want to repeat all the boilerplate to create the instance, which is mostly the same for all classes, and focus only on the unique part, that is, the initialization.
When should you use __new__? There are some special cases where you want to, but in general, ask yourself the question: do I need to introduce this logic before the instance is created? if yes, then you need to override __new__. If the answer is no, then you should put it in __init__
is it possible to ignore some fields when creating a Python dataclass from a .csv?
What is the way to return value when initiating a class
Videos
In essence, __new__ is responsible for creating the instance (thus, it may be accurate to say that it is the constructor, as you've noted) while __init__ is indeed a way of initializing state in an instance. For example, consider this:
class A(object):
def __new__(cls):
return object.__new__(cls)
def __init__(self):
self.instance_method()
def instance_method(self):
print 'success!'
newA = A()
Notice that __init__ receives the argument self, while __new__ receives the class (cls). Since self is a reference to the instance, this should tell you quite evidently that the instance is already created by the time __init__ gets called, since it gets passed the instance. It's also possible to call instance methods precisely because the instance has already been created.
As to your second question, there is rarely a need in my experience to use __new__. To be sure, there are situations where more advanced techniques might make use of __new__, but those are rare. One notorious example where people might be tempted to use __new__ is in the creation of the Singleton class (whether that's a good technique or not, however, isn't the point).
For better or worse, you basically get to control the process of instantiation, and whatever that might mean in your specific situation.
__init__ is called with an already built up instance of the object as first parameter (normally called self, but that's just a parameter name).
__new__ instead is called passing the class as first parameter and is expected to return an instance (that will be later passed to __init__).
This allows for example __new__ to return an already-existent instance for value-based objects that are immutable and for which identity shouldn't play a role.