#python #наследование #множественное_наследование
Копипаст из idle class A(object): def go(self): print("go A go!") def stop(self): print("stop A stop!") def pause(self): raise Exception("Not Implemented") class B(A): def go(self): super(B, self).stop() print("go B go!") class C(A): def go(self): super(C, self).go() print("go C go!") def stop(self): super(C, self).stop() print("stop C stop!") class E(B,C): pass e=E() e.go() вывел stop A stop! stop C stop! go B go! Непонятно откуда такой вывод
Ответы
Ответ 1
Сначала немного теории: Когда вы дёргаете метод у объекта, интерпретатор пытается найти этот метод сначала у самого объекта, если не находит - то ищет у класса объекта, если и там не находит, то по очереди обходит всех предков класса, пока не найдёт. Порядок обхода предков при множественном наследовании определяется алгоритмом MRO C3. Хорошая статья об этом есть на Хабре: https://habr.com/ru/post/62203/ Для вашего класса E в соответствии с MRO C3 порядок обхода родителей будет таким: E -> B -> C -> A -> object В этом легко убедиться так: print(E.__mro__) Теперь по пунктам, что происходит в вашем коде: Вы дёргаете для объекта e метод go Интерпретатор ищёт go в e. Не находит. Ищет go в классе E. Не находит. Ищет go в классе B. Находит, начинает исполнять. Ему нужно выполнить super(B, self).stop() Так как в данном случае self - это e (то есть объект класса E), то он будет делать обход в соответствии с порядком B -> C -> A. И, следовательно, будет искать stop не среди предков класса B, а в следующем по цепочке классе C. В C метод stop есть, но в нём делается сначала super(C, self).stop() поэтому интерпретатор пойдёт в A.stop В A.stop он напечатает "stop A stop!", после чего вернётся в C.stop В C.stop он напечатает "stop C stop!", после чего вернётся в B.go В B.go он напечатает "go B go!" Вот и всё :)
Комментариев нет:
Отправить комментарий