Ответ 1
__new__
статический метод позволяет использовать прецедент при создании в нем экземпляра подкласса:
return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)
Если new
- метод класса, то указанное выше записывается как:
return super(<currentclass>, cls).new(*args, **kwargs)
и нет места для размещения subcls
.
Я действительно не вижу, когда это было бы правильным использованием
__new__
. Может быть, я этого не вижу, но мне кажется, что это полностью патологическое его использование (и нужно сказать, что если вы все еще этого хотите, тогда вы можете получить доступ к нему с помощьюobject.__new__.__func__
). По крайней мере, мне очень трудно представить, что это было бы причиной того, что Гвидо изменил бы__new__
как метод класса на статический метод.
Более распространенным случаем является вызов parent __new__
без использования super()
. Вам нужно место, чтобы передать cls
явно в этом случае:
class Base(object):
@classmethod
def new(cls):
print("Base.new(%r)" % (cls,))
return cls()
class UseSuper(Base):
@classmethod
def new(cls):
print("UseSuper.new(%r)" % (cls,))
return super(UseSuper, cls).new() # passes cls as the first arg
class NoSuper(Base):
@classmethod
def new(cls):
print("NoSuper.new(%r)" % (cls,))
return Base.new() # passes Base as the first arg
class UseFunc(Base):
@classmethod
def new(cls):
print("UseFunc.new(%r)" % (cls,))
return Base.new.im_func(cls) # or `.__func__(cls)`. # passes cls as the first arg
print(UseSuper.new())
print('-'*60)
print(NoSuper.new())
print('-'*60)
print(UseFunc.new())