Super вызывает следующий метод из порядка разрешения методов (MRO) производного класса.
Каждая реализация метода f должна вызывать super, родительские классы не должны знать друг о друге, super автоматически вызовет следующий метод в MRO.
Редактировать: Я забыл, что последний класс в mro всегда является объектом. У объекта нет метода с именем f. поэтому вам следует позаботиться о том, чтобы последний класс в mro, который имеет этот метод, либо не вызывал super (). f, либо перехватывал AttributeError.
Пока вы следуете правилам линеаризации C3, дочерний класс может изменить MRO. Это означает, что производный класс определяет, какой код запускается, а какой код не запускается. Это один из способов внедрения зависимости.
Вы можете проверить MRO класса по атрибуту __mro__.
Этот ответ в основном основан на разговоре супер, считаемом супер Раймонд Хеттингер
class P1:
def f(self):
super().f()
print('P1')
class P2:
def f(self):
print('P2')
class C(P1, P2):
def f(self):
super().f()
print('C')
class C2(P2, P1):
def f(self):
super().f()
print('C2')
>>> C().f()
P2
P1
C
>>> C2().f()
P2
C2
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)
>>> C2.__mro__
(<class '__main__.C2'>, <class '__main__.P2'>, <class '__main__.P1'>, <type 'object'>)