#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!" Вот и всё :)
Комментариев нет:
Отправить комментарий