2

In the example below - taken from Python Crash Course book - why do we pass make, model and year to the subclass __init__ method?

Isn't super() supposed to already transfer those parameters to the subclass's __init__ method automatically?

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)
barciewicz
  • 3,511
  • 6
  • 32
  • 72
  • This code does not "pass `make`, `model` and `year` to the subclass `__init__` method" – ForceBru Dec 28 '18 at 14:49
  • 2
    If you aren't doing anything else in it, there's no reason to have an `ElectricCar.__init__` at all, as it inherits the one from `Car`. – Patrick Haugh Dec 28 '18 at 14:53
  • @PatrickHaugh This is what I thought as well. I wonder what was the reason for providing such example in this otherwise excellent book. – barciewicz Dec 28 '18 at 15:01

2 Answers2

2

why do we pass make, model and year to the subclass init method?

How else would it pass them to it's superclass ?

Isn't super() supposed to already transfer those parameters to the subclass's init method automatically?

No. Super() returns a proxy to the next class in the MRO (cf How does Python's "super" do the right thing? for more about the super object etc). And it's not "transfering" "to the subclass", it's the subclass that uses super() to call the parent's implementation.

Note that in this example, the ElectricCar's __init__ method is totally useless - it only delegates to the parent and do nothing else, so you can just remove it and the parent's __init__ will be automatically used instead. The point of super() is to call on the parent's method when you specialize it in the child class, ie:

class Parent():
   def __init__(self, foo):
       self.foo = foo


class Child(Parent):
   def __init__(self, foo):
       super().__init__(foo)
       # doing something more...
       self.bar = 42
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
0

While your wording wasn't quite right (the arguments are actually passed from the subclass to the superclass), the answer is yes, you need to manually pass the arguments in for super().__init__(*args, **kwargs). Otherwise you will encounter a TypeError complaining about the missing required positional/keyword arguments.

In your example, it seemed unnecessary but you trimmed a key line after the super().__init__():

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

This makes it necessary to redefine the __init__ in your subclass ElectricCar, as Car doesn't have the attribute battery.

Note that for immutable superclass however, you don't need to pass in any argument:

class Foo(int):
    def __init__(self, value):
        self.value = value
        super().__init__()

It would just take your subclass arguments as is at the point of __new__(). In this case, if you did manually pass in any argument, to the super().__init(), the interpreter would complain that the superclass's __init__ method doesn't take any argument. You can quickly see why this seems useless, but here's a related question on properly inheriting from str/int (if necessary).

r.ook
  • 13,466
  • 2
  • 22
  • 39