Лично я нахожу, что "__init__
не конструктор" - это очень хорошая укладка волос.
__init__
вызывается при запросе нового объекта. Предполагается использовать его аргументы для присвоения атрибутов новому объекту, так что устанавливаются необходимые инварианты для нормальной работы объекта. Объект уже является допустимым существующим местом для хранения атрибутов к моменту запуска кода в __init__
. Новый объект обычно не имеет атрибутов, определенных на нем, когда код в __init__
начинает работать (кроме тех, которыми обладают все объекты).
Конструктор C ++ вызывается при запросе нового объекта. Предполагается использовать его аргументы для присваивания полям нового объекта, чтобы были установлены необходимые инварианты для нормальной работы объекта. Объект уже является допустимым существующим местом для хранения полей к моменту запуска кода в конструкторе. Новый объект уже имеет все объявленные поля, когда код в конструкторе начинает выполняться, но они содержат мусор.
Java-конструктор вызывается при запросе нового объекта. Предполагается использовать его аргументы для присваивания полям нового объекта, чтобы были установлены необходимые инварианты для нормальной работы объекта. Объект уже является допустимым существующим местом для хранения полей к моменту запуска кода в конструкторе. Новый объект имеет все объявленные поля уже при запуске кода в конструкторе со значениями по умолчанию.
Основное различие между методом __init__
и конструктором C ++ / Java заключается в последнем предложенном мною предложении, и именно в этом заключается разница между статической природой Java / C ++ и динамической природой Python. Я не думаю, что это дает основание называть их принципиально разными понятиями, которые нельзя называть одним и тем же словом.
Я думаю, что главная причина, по которой Pythonistas не любит ссылаться на __init__
как на конструктора, заключается в том, что люди считают конструкторов C ++ / Java «созданием нового объекта», потому что это то, что они кажутся делать, когда вы звоните им. Но на самом деле происходит две вещи, когда вы вызываете конструктор; создается новый объект, а затем вызывается конструктор для его инициализации. В C ++ / Java часть «создать новый объект» невидима, в то время как это может быть открыто / настроено в Python (с помощью метода __new__
).
Так что, хотя роль метода __init__
очень похожа на роль конструктора C ++ / Java, некоторые люди предпочитают подчеркивать тот факт, что это не весь процесс, говоря, что «__init__
не является конструктор ".