8

I am trying to understand what objects are created when we instantiate the child class in Python, for example:

class Car():
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

class ElectricCar(Car):
     def __init__(self, make, model, year):
          super().__init__(make, model, year)

my_tesla = ElectricCar('tesla', 'model s', 2016)

When we create the object my_tesla, we instantiate the class ElectricCar by calling the constructor of this class, which in his turn calls the constructor of the parent. How does it happen? Right now I have two guesses:

1) super() is just the reference to the parent class, so we call the constructor of the parent by "super().init(make, model, year)" instantiating our child class. As a result we have just ONE object of our class ElectricCar().

2) super(), calls the constructor of the parent, create the object of the "Car" class, then we call the constructor of this object, by "super().init(make, model, year)". As a result we have TWO objects: one object of the class Car() and one object of the class ElectiricCar, in our case they are the same though.

Which one is correct? If neither then please explain what exactly happens in the:

 super().__init__(make, model, year)
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Victor Di
  • 988
  • 10
  • 16
  • 3
    no. you still only have one object, an `ElectricCar`. a constructor is a function like any other. it doesn't "create" an object for you - by the time the constructor is executed, the object was already created by the underlying runtime. constructors are just there to INITIALIZE that new object. so calling super().__init__ just runs a plain object method. the fact that that method is a constructor is irrelevant. it's a constructor only when it's auto-executed by the object builder. – Marc B Jul 04 '16 at 14:09
  • 1
    http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods – jbat100 Jul 04 '16 at 14:11

1 Answers1

10

__init__ isn't a constructor, it's an initializer. By the time __init__ is called, the objects has already been constructed (via __new__). So you get only one object, but it's initialized twice - for example, ElectricCar.__init__ may decide to re-initialize self.model after Car.__init__ has been run.

When calling super(), the appropriate baseclass is looked up in the context of the current instance. Basically, super().__init__(make, model, year) could be rewritten as Car.__init__(self, make, model, year) in your example.

This is why in earlier versions of python, the call was actually super(ElectricCar, self) - it looks up the baseclass of the current class (ElectricCar) and uses the current instance (self) as if it were an instance of that class instead.

Note that initializing doesn't mean preparing the object, it means preparing the object's state. An object is fully functional even when it does not implement __init__.


To clarify: When you call ElectricCar(), what is actually executed is close to this:

that_object = ElectricCar.__new__()  # this will actually use object.__new__
if isinstance(that_object, ElectricCar):
    ElectricCar.__init__(that_object)
return that_object

That means you have one object from the call to ElectricCar.__new__. The call to ElectricCar.__init__ will only modify/initialize that object. It may do so using other functions, such as Car.__init__.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
  • so, the objects of the two classes are created in any case? and by: super().__init__(make, model, year) we just initialize our ElectricCar object? And as result we have one object of the Car class not initialized and an object of ElectricCar class initialized? – Victor Di Jul 04 '16 at 14:21
  • Only *one* object is created, namely when you call `ElectricCar()`. *That* object is then used as `that_object.__init__()`, which resolves to `ElectricCar.__init__(self=that_object)`, which uses super to call `Car.__init__(self=that_object)`. – MisterMiyagi Jul 04 '16 at 14:34