Ответ 1
Нет, вы не можете. Вызов super()
должен знать, к какому классу относится этот метод, для поиска базовых классов для переопределенного метода.
Если вы перейдете в self.__class__
(или еще лучше, type(self)
), то super()
задана неправильная стартовая точка для поиска методов и в конечном итоге вызовет свой собственный метод снова.
См. это как указатель в списке классов, которые формируют последовательность порядка разрешения метода. Если вы пройдете в type(self)
, тогда указатель будет ссылаться на любые подклассы вместо исходной начальной точки.
Следующий код приводит к ошибке бесконечной рекурсии:
class Base(object):
def method(self):
print 'original'
class Derived(Base):
def method(self):
print 'derived'
super(type(self), self).method()
class Subclass(Derived):
def method(self):
print 'subclass of derived'
super(Subclass, self).method()
Демо:
>>> Subclass().method()
subclass of derived
derived
derived
derived
<... *many* lines removed ...>
File "<stdin>", line 4, in method
File "<stdin>", line 4, in method
File "<stdin>", line 4, in method
RuntimeError: maximum recursion depth exceeded while calling a Python object
потому что type(self)
Subclass
, не Derived
, в Derived.method()
.
В этом примере MRO для Subclass
составляет [Subclass, Derived, Base]
, а super()
должен знать, с чего начать поиск любых переопределенных методов. Используя type(self)
, вы сообщите ему, чтобы он начинался с Subclass
, поэтому он найдет следующий Derived.method()
, с которого мы начали.