В Python поддерживается множественное наследование, и вызовы методов родителей управляются с помощью линейной последовательности разрешения методов (MRO — Method Resolution Order). Функция super() позволяет вызвать метод суперкласса в иерархии и особенно полезна при сложном наследовании.
super() гарантирует корректный вызов методов согласно MRO, а не только у непосредственного родителя.
class A: def do(self): print('A') class B(A): def do(self): print('B') super().do() class C(A): def do(self): print('C') super().do() class D(B, C): def do(self): print('D') super().do() D().do() # Выведет: # D # B # C # A
Тонкости: Каждый метод обязан вызывать super(), иначе MRO "сломается". Также, конструкторы (__init__) должны вызывать super().__init__().
Вопрос: Что произойдет, если в иерархии множественного наследования один из классов "забудет" вызвать super() в своём методе?
Ответ: MRO будет нарушен, часть методов родителей просто не вызовется. Пример:
class A: def show(self): print('A') class B(A): def show(self): print('B') class C(A): def show(self): print('C') super().show() class D(B, C): def show(self): print('D'); super().show() D().show() # Выведет: D B # А методы C и A не вызываются вовсе
История
super().__init__() у одного из промежуточных классов. В результате один из виджетов не инициализировался должным образом, на что "указал" лишь редкий баг.История
История
В сложной иерархии миксинов при overrides один метод "забыл" вызвать super(). Это привело к тому, что c одного API endpoint-а не работала валидация, а с другого — проходила корректно. Ошибку нашли спустя недели, изучая MRO вручную.