6
#!/usr/bin/python

class Parent(object):        # define parent class
   parentAttr = 100
   def __init__(self):
      print "Calling parent constructor"

   def parentMethod(self):
      print 'Calling parent method'

   def setAttr(self, attr):
      Parent.parentAttr = attr

   def getAttr(self):
      print "Parent attribute :", Parent.parentAttr


class Child(Parent): # define child class
   def __init__(self):
      print "Calling child constructor"

   def childMethod(self):
      print 'Calling child method'


c = Child()          # instance of child

I have called created an instance of the Child class here.It doesn't seem to call the constructor of the parent class.The output looks like shown below.

Calling child constructor

In C++ for example when you call the constructor of a derived class the base class constructor get called first.Why is this not happening in Python?

liv2hak
  • 14,472
  • 53
  • 157
  • 270

3 Answers3

13

From the Zen of Python:

Explicit is better than implicit.

Should Python call the parent constructor before or after the child constructor? With what arguments? Not knowing, it leaves it to you to decide.

class Child(Parent): # define child class
    def __init__(self):
        super(Child, self).__init__()  # call the appropriate superclass constructor
        print "Calling child constructor"

See also this StackOverflow post for the benefits of using super().

Community
  • 1
  • 1
Jim Garrison
  • 4,199
  • 4
  • 25
  • 39
5

You need to explicity call the parent constructor in the __init__ method of the child class. Try:

class Child(Parent): # define child class
   def __init__(self):
      Parent.__init__(self)
      print "Calling child constructor"
  • 1
    While this will work in this trivial case, once you get into multi-inheritance, it is rather brittle. Better to use `super`, per Jim Garrison's answer, which will be equivalent here, and continue to do the right thing in more complex cirumstances. – lvc Apr 03 '13 at 01:56
2

If you have Python 3.x, you can run this instead (it is nearly what you are doing in your own code):

#! /usr/bin/env python3

def main():
    c = Child()
    c.method_a()
    c.method_b()
    c.get_attr()
    c.set_attr(200)
    Child().get_attr()

class Parent:

    static_attr = 100

    def __init__(self):
        print('Calling parent constructor')

    def method_a(self):
        print('Calling parent method')

    def set_attr(self, value):
        type(self).static_attr = value

    def get_attr(self):
        print('Parent attribute:', self.static_attr)

class Child(Parent):

    def __init__(self):
        print('Calling child constructor')
        super().__init__()

    def method_b(self):
        print('Calling child method')

if __name__ == '__main__':
    main()
Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117