110

Why are constructors indeed called "Constructors"? What is their purpose and how are they different from methods in a class?

Also, can there be more that one __init__ in a class? I tried the following, can someone please explain the result?

>>> class test:
    def __init__(self):
        print "init 1"
    def __init__(self):
        print "init 2"

>>> s=test()
init 2

Finally, is __init__ an operator overloader?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Arindam Roychowdhury
  • 5,927
  • 5
  • 55
  • 63
  • 42
    Technically, `__init__` is an *initialiser*. The python *constructor* is `__new__`. Python uses automatic two-phase initialisation - `__new__` returns a valid but (usually) unpopulated object (see `bool` for a counter-example), which then has `__init__` called on it automatically. This avoids the problems languages like C++ have with partially-constructed objects - you never have one in Python (though it may be partially-initialised). You will almost never need to override both `__new__` and `__init__` on a class. – Tim Delaney Jan 25 '12 at 02:46
  • 2
    @TimDelaney: I am not sure what you mean with partially-constructed objects in C++. – Sebastian Mach Dec 17 '14 at 09:28
  • 11
    @phresnel In C++ the type of the object is the base class (not the subclass) while in the base class constructor. You can't call a virtual method in the base class constructor and have the subclass provide the implementation. In Java you can call a subclass method in the base class constructor, but the subclass member variables will automatically initialised *after* the base class constructor (and method call). In languages with two-phase initialisation like Python, you can happily call methods in the base class initialiser and have the subclass provide (or override) the behaviour. – Tim Delaney Dec 21 '14 at 12:54
  • 4
    @TimDelaney. I think that your comment should replace the accepted answer. – flamenco Nov 11 '16 at 17:14
  • In the words of Mark Lutz (from the book Learning Python), " By itself, Python uses inheritance to look for and call only _one_ **__init__ ** method at construction time - the lowest in the tree." – Arindam Roychowdhury Oct 12 '17 at 06:21

5 Answers5

115

There is no function overloading in Python, meaning that you can't have multiple functions with the same name but different arguments.

In your code example, you're not overloading __init__(). What happens is that the second definition rebinds the name __init__ to the new method, rendering the first method inaccessible.

As to your general question about constructors, Wikipedia is a good starting point. For Python-specific stuff, I highly recommend the Python docs.

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Does it also mean the source file is parsed(interpreted?) sequentially? Can I be sure whatever function I have defined later overwrites the one defined with same name in prior? :( my Q sounds silly.. should have known it – 0xc0de Jan 24 '12 at 11:38
  • 4
    @0xc0de: In Python, function definitions are actually *executable statements* and are run top to bottom, so yes. – NPE Jan 24 '12 at 11:40
  • 1
    @0xc0de What actually happens is that the body of the class is executed in it's own namespace, that namespace is then passed to the metaclass (among with the name and bases). Function definitions then are just creating a function with the specified body and assigning it to it's name. The last assignment to `__init__` will be what ends up in the class. – skyking Sep 24 '15 at 10:07
66

Why are constructors indeed called "Constructors" ?

The constructor (named __new__) creates and returns a new instance of the class. So the C.__new__ class method is the constructor for the class C.

The C.__init__ instance method is called on a specific instance, after it is created, to initialise it before being passed back to the caller. So that method is the initialiser for new instances of C.

How are they different from methods in a class?

As stated in the official documentation __init__ is called after the instance is created. Other methods do not receive this treatment.

What is their purpose?

The purpose of the constructor C.__new__ is to define custom behaviour during construction of a new C instance.

The purpose of the initialiser C.__init__ is to define custom initialisation of each instance of C after it is created.

For example Python allows you to do:

class Test(object):
    pass

t = Test()

t.x = 10   # here you're building your object t
print t.x

But if you want every instance of Test to have an attribute x equal to 10, you can put that code inside __init__:

class Test(object):
    def __init__(self):
        self.x = 10

t = Test()
print t.x

Every instance method (a method called on a specific instance of a class) receives the instance as its first argument. That argument is conventionally named self.

Class methods, such as the constructor __new__, instead receive the class as their first argument.

Now, if you want custom values for the x attribute all you have to do is pass that value as argument to __init__:

class Test(object):
    def __init__(self, x):
        self.x = x

t = Test(10)
print t.x
z = Test(20)
print t.x

I hope this will help you clear some doubts, and since you've already received good answers to the other questions I will stop here :)

Rik Poggi
  • 28,332
  • 6
  • 65
  • 82
9

Classes are simply blueprints to create objects from. The constructor is some code that are run every time you create an object. Therefor it does'nt make sense to have two constructors. What happens is that the second over write the first.

What you typically use them for is create variables for that object like this:

>>> class testing:
...     def __init__(self, init_value):
...         self.some_value = init_value

So what you could do then is to create an object from this class like this:

>>> testobject = testing(5)

The testobject will then have an object called some_value that in this sample will be 5.

>>> testobject.some_value
5

But you don't need to set a value for each object like i did in my sample. You can also do like this:

>>> class testing:
...     def __init__(self):
...         self.some_value = 5

then the value of some_value will be 5 and you don't have to set it when you create the object.

>>> testobject = testing()
>>> testobject.some_value
5

the >>> and ... in my sample is not what you write. It's how it would look in pyshell...

Niclas Nilsson
  • 5,691
  • 3
  • 30
  • 43
1

coonstructors are called automatically when you create a new object, thereby "constructing" the object. The reason you can have more than one init is because names are just references in python, and you are allowed to change what each variable references whenever you want (hence dynamic typing)

def func(): #now func refers to an empty funcion
    pass
...
func=5      #now func refers to the number 5
def func():
    print "something"    #now func refers to a different function

in your class definition, it just keeps the later one

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
0

There is no notion of method overloading in Python. But you can achieve a similar effect by specifying optional and keyword arguments

NLPer
  • 511
  • 1
  • 4
  • 9