Я играл с множественным наследованием в python и столкнулся с ситуацией, когда не могу понять, как это происходит.
Вот схема наследования:
A F
/ \ |
B C |
\ | /
\ | /
D
Бриллиант ABCD, знакомый каждому. Плюс дополнительный класс "F" я добавляю для прикола.
Вот код:
class A(object):
def foo(self, call_from):
print "foo from A, call from %s" % call_from
super(A, self).foo("A")
class B(A):
def foo(self, call_from):
print "foo from B, call from %s" % call_from
super(B, self).foo("B")
class C(A):
def foo(self, call_from):
print "foo from C, call from %s" % call_from
super(C, self).foo("C")
class F(object):
def foo(self, call_from):
print "foo from F, call from %s" % call_from
class D(B, C, F):
def foo(self):
print "foo from D"
super(D, self).foo("D")
выход:
>>> d = D()
>>> d.foo()
foo from D
foo from B, call from D
foo from C, call from B
foo from A, call from C
foo from F, call from A
Порядок разрешения метода:
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.F'>, <type 'object'>)
foo from C, call from B
вместоfoo from C, call from D
foo from F, call from A
просто скинь меня...Кажется, что super()
связаны в соответствии с порядком разрешения методов и игнорируют отношения между классами, но я не уверен.
Может ли кто-нибудь указать мне правильное направление, чтобы понять это поведение?
Пожалуйста, имейте в виду, что я пытаюсь понять сам язык. Не пытаясь решить практическую проблему. Так что у меня нет варианта использования для этого. Но было бы хорошо, если бы кто-нибудь указал вариант использования:)
UPDATE:
To summarize - super() simply let you know what is next to call base on the mro. It is not necessary the parent. While mro built base on the inheritance hierarchy, mro itself is not the inheritance hierarchy.