I'm trying to understand how the __init__ methods function in Python, especially when dealing with inheritance. For instance, consider this code:
```python
class Rectangle:
def __init__(self, height, width):
self.height = height
self.width = width
print(f"Height was set to {self.height}")
print(f"Width was set to {self.width}")
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
s = Square(1)
```
I know `super` is a class in Python, so when I call `super().__init__(side, side)`, it creates an instance of the super class and calls the `__init__` method of that class. But how does this all work to set the attributes of the object `s`? And why doesn't calling `Rectangle.__init__(self, side, side)` behave the same?
Also, why does calling `Rectangle.__init__(self, side, side)` work to set `s`'s attributes if it's calling the `__init__` method directly from the `Rectangle` class? I'm really curious about the underlying mechanics here!
2 Answers
So, `super()` is basically your way of accessing methods from the parent class. In your `Square` class, when you call `super().__init__(side, side)`, you're invoking the initialization method of `Rectangle`. This is important because even though `Square` overrides the `__init__` method, it still needs to handle the attributes from `Rectangle`. That's where `super()` comes in. It finds the parent class and calls its `__init__` method, giving `s` its `height` and `width`. But if you directly call `Rectangle.__init__(self, side, side)`, you're bypassing the `super` mechanism and calling the parent's method directly. Both methods work, but `super()` is usually the cleaner approach, especially in more complex inheritance hierarchies!
If you're looking for a deep dive, check out this video! It's super helpful for visualizing how inheritance and `super()` work in Python: [https://youtu.be/X1PQ7zzltz4?si=RTloEyO4Cx-ivTWJ](https://youtu.be/X1PQ7zzltz4?si=RTloEyO4Cx-ivTWJ) Just make sure you're ready for a bit of a time commitment since it's 21 minutes long!
Is 21 minutes really the best way to understand this? Wouldn't some shorter resources do the trick?
Exactly! Using `super()` is highly recommended because it also respects the method resolution order, which is super useful in multiple inheritance scenarios.