John David
John David

Reputation: 131

Difference between invoking parent class via super vs the parent class name?

In the code:

class Mother(object):
    def __init__(self):
        self._haircolor = "Brown"

class Child(Mother):
    def __init__(self): 
        #Mother.__init__(self)
        super(Mother, self).__init__(self)

    def print_haircolor(self):
        print self._haircolor

c = Child()
c.print_haircolor()

Why does Mother.__init__(self) work fine (it outputs Brown), but super(Mother, self).__init__(self) give the error

Traceback (most recent call last):
  File "test2.py", line 13, in <module>
    c = Child()
  File "test2.py", line 8, in __init__
    super(Mother, self).__init__(self)
TypeError: object.__init__() takes no parameters

I've seen this, this, this and this, but it doesn't answer the question.

Upvotes: 0

Views: 211

Answers (1)

Chris
Chris

Reputation: 22953

You have two related issues.

First, as the error states, object.__init__() takes no arguments, but by running super(Mother, self).__init__(self), you're trying to pass in an instance of Child to the constructor of object. Just run super(Mother, self).__init__().

But second and more importantly, you're not using super correctly. If you want to run the constructor of the Mother class in Child, you need to pass in the subclass Child, not the superclass Mother. Thus, what you want is super(Child, self).__init__(self).

When these fixes are added to your code, it runs as expected:

class Mother(object):
    def __init__(self):
        self.haircolor = "Brown"

class Child(Mother):
    def __init__(self): 
        super(Child, self).__init__()

    def print_haircolor(self):
        print self.haircolor

c = Child()
c.print_haircolor() # output: brown

Upvotes: 4

Related Questions