12

I'm trying to understand how parent and child classes in Python work and I ran into this seemingly simple problem:

class parent(object):

    def __init__(self):
        self.data = 42


class child(parent):

    def __init__(self):
        self.string = 'is the answer!'

    def printDataAndString(self):
        print( str(self.data) + ' ' + self.string )


c = child()
c.printDataAndString()

I'm expecting the string 42 is the answer! but I get

AttributeError: 'child' object has no attribute 'data'

What am I missing?

I experimentated with pass and also super(parent,...) but couldn't get it right.

Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • 1
    FWIW, you _could_ call the parent `__init__` using `parent.__init__(self)`, but using `super` is preferred because it handle multiple inheritance properly. – PM 2Ring Sep 03 '15 at 10:13

1 Answers1

13

Since your child has its own __init__() function, you need to call the parent class' __init__() , otherwise it does not get called. Example -

def __init__(self):
    super(child,self).__init__()
    self.string = 'is the answer!'

super() from documentation -

super(type[, object-or-type])

Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.

So the first argument to super() should be the child class (whose' parent class' method you want to call) , and the second argument should be the object itself , that is self. Hence , super(child, self) .

In Python 3.x , you can simply call -

super().__init__()

And it would call the __init__() method from the correct parent class.

Community
  • 1
  • 1
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
  • What if the `_init_` function of my parent class contains a lot of variable declarations and some heavyweight file-io - is there are way to just get specific variables? Otherwise everytime I create an instance of my child class, it would call the `_init_` function of my parent class, which I guess would be a little overkill if I just need that one or two variables? – Robert Seifert Sep 03 '15 at 10:11
  • Wouldn't it be possible to define those one or two variables in the child class itself , and not call the `super().__init__()` . – Anand S Kumar Sep 03 '15 at 10:14
  • 1
    @thewaywewalk: The simple answer is what Anand says: simply declare those variables in the child's `__init__` method and don't call the parent's `__init__` method. However, if the child doesn't need all that extra stuff, then you should consider reorganizing the inheritance and swapping the roles of parent & child. The parent class ought to be the base class, with the child classes having the fancy added extras. – PM 2Ring Sep 03 '15 at 10:17