Когда (и почему) была введена функция 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 способ сделать это.