__init__ as a constructor?

If you have a class Foo then:

  • Foo() is the constructor
  • Foo.__init__() is the initializer
  • Foo.__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".


Constructor returns an instance and can fail. But __init__ does not return an instance. Even when __init__ raises and exception, __del__ is called to delete the instance.

This can be seen here:

class A(object):
    def __init__(self):
        raise ValueError

    def __del__(self):
        print "Called"

def main():
    try:
        a = A()
    except ValueError, e:
        print "ValueError"

if __name__ == '__main__':
    main()

__new__ on the other hand, returns an instance.