Ответ 1
Форма с двумя аргументами нужна только в Python 2. Причина в том, что self.__class__
всегда ссылается на класс "leaf" в дереве наследования - то есть на самом конкретном классе объекта, но когда вы вызываете super
, вам нужно указать, какая реализация в настоящее время вызывается, поэтому она может вызывать следующую в дереве наследования.
Предположим, что у вас есть:
class A(object):
def foo(self):
pass
class B(A):
def foo(self):
super(self.__class__, self).foo()
class C(B):
def foo(self):
super(self.__class__, self).foo()
c = C()
Обратите внимание, что c.__class__
всегда C
. Теперь подумайте, что произойдет, если вы вызываете c.foo()
.
Когда вы вызываете super(self.__class__, self)
в методе C, он будет похож на вызов super(C, self)
, что означает "вызывать версию этого метода, унаследованного C". Это вызовет B.foo
, что хорошо. Но когда вы вызываете super(self.__class__, self)
из B, ему все равно нравится называть super(C, self)
, потому что он тот же self
, поэтому self.__class__
по-прежнему C
. В результате вызов в B снова вызовет B.foo
и произойдет бесконечная рекурсия.
Конечно, то, что вы действительно хотите, это вызов super(classThatDefinedTheImplementationThatIsCurrentlyExecuting, self)
, и это действительно то, что делает Python 3 super()
.
В Python 3 вы можете просто сделать super().foo()
, и он поступает правильно. Мне непонятно, что вы имеете в виду super(self)
как ярлык. В Python 2 это не работает по причине, описанной выше. В Python 3 это будет "longcut", потому что вы можете просто использовать простой super()
.
Использование методов super(type)
и super(type1, type2)
иногда может потребоваться в Python 3, но для необычных ситуаций они всегда были более эзотерическими.