In C++, constructors are special operators. There is special syntax for calling a base class constructor:
class A { ... };
class B: public A {
public:
B() : A() { ... }
// ^^^^^
};
If the base constructor is not called explicitly, the default constructor for the base class will be called automatically.
This is important for C++'s memory model and data model:
- failing to call the base constructor could lead to uninitialised memory, and would definitely lead to UB
- classes may or may not be default constructible, which affects how explicit you need to be
Python is a very different language. It has no concept of default constructors. It has no concept of uninitialised memory. And Python constructors are just an ordinary initialization method (well, as ordinary as a dunder-method can be). There is no special syntax for calling the base class init method, it's just the same as calling any other base class method.
This kind of fits into the general Python theme of having a minimal syntax, but complex, flexible semantics. The language doesn't force you to initialize your objects properly, just as it doesn't force you to only assign specific types to some variable. As the language itself won't help you, you have to use linters to check for common mistakes.
Note that Python's flavour of multiple inheritance makes it difficult or impossible to handle "base" class constructors automatically. If the class you are writing is one of multiple bases in a multiple inheritance hierarchy, then the super().__init__()
call may not go to this classes' base but possibly to an unrelated sibling class. Handling that properly requires a conscious design effort.
Of course, the best move is not to play. As a dynamic language, there are very few circumstances where inheritance is the best solution in Python.
A
's constructor requires arguments thatB
's constructor doesn't know how to supply?super()
is called implicitly. If the superclass doesn't have a default constructor you need to specify the constructor explicitly. If the subclass can't provide the arguments, then it can't be a subclass. This doesn't cause problems in Java, although with bad design you can end up with subclasses requiring huge parameter lists for the constructor.