157

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?

4
  • 1
    Your format is wrong, is that a copy-and-paste problem? Python will bark on wrong format. Commented Oct 6, 2013 at 6:25
  • @Mingyu format is wrong? You mean indentation or am I missing something else here? Commented Oct 6, 2013 at 6:31
  • Yea.. I mean indentation. Please look at my answer below. Commented Oct 6, 2013 at 6:35
  • 4
    don't use derived class name do this in python 3 (pseudocode): super().__init__(args...) Commented Jan 20, 2020 at 17:00

4 Answers 4

187

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'}
Sign up to request clarification or add additional context in comments.

5 Comments

If you pass BaseClass to super, it'll skip over BaseClass and call object.__init__, which is almost certainly not what you want.
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.
Thanks, @abarnert. Initially, he did not post his code and the question he asked is the one in the title.
Your answer is the most highly voted. You should really reference how to not use the derived class name by doing super().__init__(args)
@CharlieParker can you please expand? What should we not do?
94

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()

4 Comments

Can you give any explanation for the recommendation 'not to use the Derived class's name'?
@jwg I updated the answer to explain why class is a better choice.
@CraigFinch it doesn't seem to be a good idea at all to use self.__class__. In Python 3 you can simply use super().__init__
Yet another reason Py3 is superior to Py2. (As someone who came to python after 3.4 came out)
20

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.

2 Comments

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 Most likely because it was that way in the OP's question. I would agree that the reverse is usually better.
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

1 Comment

don't use derived class name do this in python 3 (pseudocode): super().__init__(args...)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.