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