Java и C ++ требуют, чтобы конструктор базового класса вызывался из-за разметки памяти.
Если у вас есть класс BaseClassс членом field1, и вы создаете новый класс, SubClassкоторый добавляет член field2, то экземпляр SubClassсодержит пространство для field1и field2. Вам нужен конструктор BaseClassдля заполнения field1, если только вы не требуете, чтобы все наследующие классы повторяли BaseClassинициализацию в своих собственных конструкторах. И если field1это private, то наследующие классы не могут инициализироваться field1.
Python не является Java или C ++. Все экземпляры всех пользовательских классов имеют одинаковую «форму». В основном это просто словари, в которые можно вставлять атрибуты. Перед выполнением любой инициализации все экземпляры всех пользовательских классов практически одинаковы ; это просто места для хранения атрибутов, которые еще не хранятся.
Поэтому для подкласса Python имеет смысл не вызывать конструктор базового класса. Он может просто добавить атрибуты сам, если захочет. Нет места, зарезервированного для данного числа полей для каждого класса в иерархии, и нет разницы между атрибутом, добавленным кодом из BaseClassметода, и атрибутом, добавленным кодом из SubClassметода.
Если, как это обычно бывает, на SubClassсамом деле нужно BaseClassнастроить все инварианты, прежде чем он продолжит выполнять свою собственную настройку, тогда да, вы можете просто позвонить BaseClass.__init__()(или использовать super, но это сложно и иногда имеет свои проблемы). Но ты не обязан. И вы можете сделать это до, или после, или с другими аргументами. Черт, если бы вы хотели, вы могли бы вызвать BaseClass.__init__из другого метода полностью, чем __init__; может быть, у вас происходит какая-то странная ленивая инициализация.
Python достигает этой гибкости, сохраняя простоту. Вы инициализируете объекты, написав __init__метод, который устанавливает атрибуты self. Вот и все. Он ведет себя точно так же, как метод, потому что это точно метод. Нет других странных и не интуитивно понятных правил о том, что нужно делать в первую очередь, или о вещах, которые автоматически произойдут, если вы не будете делать другие вещи. Единственная цель, которой он должен служить, - это ловушка для выполнения во время инициализации объекта для установки начальных значений атрибута, и он делает именно это. Если вы хотите, чтобы это делало что-то другое, вы явно пишете это в своем коде.
__init__метода и даже, возможно, автоматически искать подклассы и декорировать их.