Основная цель __new__
- выделить новый экземпляр класса, а задача __init__
- создать существующий экземпляр.
Согласно документам:
__new__()
- статический метод (в специальном случае, поэтому вам не нужно объявлять его как таковой)
__init__
onС другой стороны, это правильный метод экземпляра.Кстати, его можно вызывать несколько раз в одном и том же экземпляре.
Этого должно быть достаточно для объяснения вашего терминального сеанса:
>>> cls = object
>>> self = cls()
Вы только что позвонили object.__call__
, что по сути делает
self = cls.__new__()
if isinstance(self, cls):
cls.__init__(self)
return self
Обратите внимание, что возвращаемое значение __new__
не обязательно должно быть экземпляром класса, к которому он принадлежит, но __init__
вызывается, только если это так.В вашем случае это.
>>> cls.__new__ is self.__new__
True
__new__
- статический метод, поэтому попытка связать его с экземпляром ничего не дает: он остается методом класса.Это та же самая причина, по которой вы должны явно передавать cls
при вызове super().__new__
: это одна и та же бесплатная функция, не привязанная ни к классу, ни к экземпляру.
>>> cls.__init__ is self.__init__
False
Мало того, что это не одно и то же, но их типы разные.cls.__init__
- обычная функция.self.__init__
- это связанный метод, в котором отсутствует первый параметр cls.__init__
.
>>> self.__init__()
Он уже был вызван, но для object
это неоперативный вызов, который можно вызывать столько раз, сколькотебе нравится.Обратите внимание, что первый параметр не передается, поскольку он является связанным методом.
>>> cls.__init__()
Это вызывает функцию raw __init__
, которая требует передачи параметра self
.Поскольку вы этого не делаете, это поднимает.Попробуйте вместо этого:
>>> cls.__init__(self)