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".
Is a constructor __init__ necessary for a class in Python? - Stack Overflow
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?
Videos
I see a misconception here between a constructor--constructing the object and initializing the object:
Python's use of __new__ and __init__?
Use
__new__when you need to control the creation of a new instance. Use__init__when you need to control initialization of a new instance.
So we must be careful here.
I read that the constructor is like the first argument passed to the class, which makes sense to me since the parameters seem to be passed to the class via the
__init__method.
The constructor is not passed to the class, to be precise the result of the constructor (__new__) will be the first argument for every instance method in the class or its sub-classes (note: __new__ works only for new-style classes):
class A:
def __new__(self):
return 'xyz'
See what happens when you call the class (create the object):
>>> A()
'xyz'
>>> type(A())
<class 'str'>
Calling the class no longer return instance of type A, because we changed the mechanism of the constructor __new__. Actually by doing so you alter the whole meaning of your class, not only, this is pretty much hard to decipher. It's unlikely that you'll switch the type of object during the creating time of that specific object. I hope this sentence makes sense, if not, how will it make sense in your code!
class A:
def __new__(self):
return 'xyz'
def type_check(self):
print(type(self))
Look what happens when we try to call type_check method:
>>> a = A()
>>> a
'xyz'
>>> a.type_check()
AttributeError: 'str' object has no attribute 'type_check'
a is not an object of class A, so basically you don't have access to class A anymore.
__init__ is used to initialize the object's state. Instead of calling methods that will initialize the object's members after it's created, __init__ solves this issue by initializing the object's members during creation time, so if you have a member called name inside a class and you want to initialize name when you create the class instead of calling an extra method init_name('name'), you would certainly use __init__ for this purpose.
So when I 'call' the class, I pass it the parameters from the
__init__method?
When you call the class, you pass the parameters (to) __init__ method?
Whatever arguments you pass the class, all the parameters will be passed to __init__ with one additional parameter added automatically for you which is the implied object usually called self (the instance itself) that will be passed always as the left-most argument by Python automatically:
class A:
def __init__(self, a, b):
self.a = a
self.b = b
A( 34, 35)
self.a = 34 | |
| |
| | self.b = 35
init(self, a, b)
|
|
|
The instance that you created by calling the class A()
Note: __init__ works for both classic classes and new style classes. Whereas, __new__ works only for new-style classes.
No, the constructor is just the method that is called to construct the object. It is not passed anywhere. Rather the object itself is passed automatically to all methods of the class.
Constructor is not required if you don't have anything to construct but usually you have something to do in the beginning.
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.