How to call Base Class's __init__ method from the child class?

188,785

Solution 1

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'}

Solution 2

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

Solution 3

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.

Solution 4

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

Share:
188,785
praxmon
Author by

praxmon

Working in the bay area

Updated on August 18, 2020

Comments

  • praxmon
    praxmon almost 4 years

    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?

  • abarnert
    abarnert over 10 years
    If you pass BaseClass to super, it'll skip over BaseClass and call object.__init__, which is almost certainly not what you want.
  • abarnert
    abarnert over 10 years
    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.
  • Mingyu
    Mingyu over 10 years
    Thanks, @abarnert. Initially, he did not post his code and the question he asked is the one in the title.
  • jwg
    jwg almost 9 years
    Can you give any explanation for the recommendation 'not to use the Derived class's name'?
  • Craig Finch
    Craig Finch over 8 years
    @jwg I updated the answer to explain why class is a better choice.
  • Erwin Mayer
    Erwin Mayer over 8 years
    @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__
  • Marc
    Marc almost 8 years
    Yet another reason Py3 is superior to Py2. (As someone who came to python after 3.4 came out)
  • mojoken
    mojoken over 4 years
    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?
  • Charlie Parker
    Charlie Parker over 4 years
    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
    Charlie Parker over 4 years
    don't use derived class name do this in python 3 (pseudocode): super().__init__(args...)
  • Astrid
    Astrid over 3 years
    @CharlieParker can you please expand? What should we not do?
  • MEMark
    MEMark over 2 years
    @mojoken Most likely because it was that way in the OP's question. I would agree that the reverse is usually better.