Когда (и почему) была введена функция Python __new__()
?
Есть три шага в создании экземпляра класса, например, MyClass()
:
-
MyClass.__call__()
вызывается. Этот метод должен быть определен в метаклассеMyClass
. -
MyClass.__new__()
вызывается (__call__
). Определено на самомMyClass
. Это создает экземпляр. -
MyClass.__init__()
вызывается (также__call__
). Это инициализирует экземпляр.
На создание экземпляра может повлиять либо перегрузка __call__
либо __new__
. Обычно нет особых причин перегружать __call__
вместо __new__
(например, использовать метод __call__ метакласса вместо __new__?).
У нас есть старый код (все еще работающий!), Где __call__
перегружен. Причина была в том, что __new__
не было доступно в то время. Поэтому я попытался узнать больше об истории как Python, так и нашего кода, но я не мог понять, когда был введен __new__
.
__new__
появляется в документации для Python 2.4, а не в документации для Python 2.3, но не появляется ни в одной из версий Python 2. Первый коммит, в котором было введено __new__
(слияние descr-branch обратно в trunk.), Который я смог найти, был сделан в 2001 году, но сообщение "back to trunk" указывает на то, что что-то было раньше. PEP 252 (создание типов, более похожих на классы) и PEP 253 (создание встроенных типов подтипов) нескольких месяцев назад представляются актуальными.
Если вы __new__
больше о введении __new__
вы __new__
больше о том, почему Python такой, какой он есть.
Изменить для уточнения:
Похоже, что class.__new__
дублирует функциональность, которая уже предоставлена metaclass.__call__
. Кажется неуместным добавлять метод только для лучшей репликации существующих функций.
__new__
- это один из немногих методов класса, которые вы получаете из коробки (то есть с cls
качестве первого аргумента), тем самым привнося сложность, которой раньше не было. Если класс является первым аргументом функции, то можно утверждать, что функция должна быть обычным методом метакласса. Но этот метод уже существует: __call__()
. Я чувствую, что что-то упустил.
Должен быть one-- и, предпочтительно, только один --obvious способ сделать это.