151

If I have a python class as:

class BaseClass(object):
#code and the init function of the base class

And then I define a child class such as:

class ChildClass(BaseClass):
#here I want to call the init function of the base class

If the init function of the base class takes some arguments that I am taking them as arguments of the child class's init function, how do I pass these arguments to the base class?

The code that I have written is:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super(ElectricCar, self).__init__(model, color, mpg)

Where am I going wrong?

Jim Jam
  • 713
  • 4
  • 10
  • 22
praxmon
  • 5,009
  • 22
  • 74
  • 121

4 Answers4

181

You could use super(ChildClass, self).__init__()

class BaseClass(object):
    def __init__(self, *args, **kwargs):
        pass

class ChildClass(BaseClass):
    def __init__(self, *args, **kwargs):
        super(ChildClass, self).__init__(*args, **kwargs)

Your indentation is incorrect, here's the modified code:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super(ElectricCar, self).__init__(model, color, mpg)

car = ElectricCar('battery', 'ford', 'golden', 10)
print car.__dict__

Here's the output:

{'color': 'golden', 'mpg': 10, 'model': 'ford', 'battery_type': 'battery'}
Mingyu
  • 31,751
  • 14
  • 55
  • 60
  • 2
    If you pass `BaseClass` to `super`, it'll skip over `BaseClass` and call `object.__init__`, which is almost certainly not what you want. – abarnert Oct 06 '13 at 07:29
  • 1
    Meanwhile, the only thing wrong with the OP's code is his indentation, explaining `super` (even if you explained it correctly, which you didn't) doesn't help, especially given that he already used it exactly the same way; in fact, it's character-for-character identical. – abarnert Oct 06 '13 at 07:31
  • 3
    Thanks, @abarnert. Initially, he did not post his code and the question he asked is the one in the title. – Mingyu Oct 06 '13 at 07:35
  • 6
    Your answer is the most highly voted. You should really reference how to not use the derived class name by doing `super().__init__(args)` – Charlie Parker Jan 20 '20 at 17:01
  • @CharlieParker can you please expand? What should we _not_ do? – Astrid Oct 06 '20 at 20:16
85

As Mingyu pointed out, there is a problem in formatting. Other than that, I would strongly recommend not using the Derived class's name while calling super() since it makes your code inflexible (code maintenance and inheritance issues). In Python 3, Use super().__init__ instead. Here is the code after incorporating these changes :

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):

    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super().__init__(model, color, mpg)

Thanks to Erwin Mayer for pointing out the issue in using __class__ with super()

Manjunath Reddy
  • 935
  • 7
  • 10
19

If you are using Python 3, it is recommended to simply call super() without any argument:

class Car(object):
    condition = "new"

    def __init__(self, model, color, mpg):
        self.model = model
        self.color = color
        self.mpg   = mpg

class ElectricCar(Car):
    def __init__(self, battery_type, model, color, mpg):
        self.battery_type=battery_type
        super().__init__(model, color, mpg)

car = ElectricCar('battery', 'ford', 'golden', 10)
print car.__dict__

Do not call super with class as it may lead to infinite recursion exceptions as per this answer.

Community
  • 1
  • 1
Erwin Mayer
  • 18,076
  • 9
  • 88
  • 126
  • 7
    Just curious why all the answers in this question are setting self.battery_type before calling the super init method. Isn't it considered better practice to call super init before modifying anything in the object, so the base class is fully initialized first? Or am I missing something here? – mojoken Jan 03 '20 at 23:29
  • @mojoken Most likely because it was that way in the OP's question. I would agree that the reverse is usually better. – MEMark Feb 06 '22 at 16:48
15

You can call the super class's constructor like this

class A(object):
    def __init__(self, number):
        print "parent", number

class B(A):
    def __init__(self):
        super(B, self).__init__(5)

b = B()

NOTE:

This will work only when the parent class inherits object

thefourtheye
  • 233,700
  • 52
  • 457
  • 497