Could somebody explain why this code prints Y and not X? I expected it to print “X” because it says pass in Class C and Class X is the next super class.
class X: def foo(self): return "X" class Y: def foo(self): return "Y" class A(X): def foo(self): return self.met() class B(A): def foo(self): return "B" class C(X): pass class D(C, X): def met(self): return "D" class E(A, D): def foo(self): return super().foo() class F(Y,B): pass class G(D, B): pass class H(E, A, X): def met(self): return "H" class I(G,F): pass print(I().foo())
Sorry for the long code, but I dont know how to make it shorter without making the question unclear
Advertisement
Answer
Per Python Multiple Inheritance: The Diamond Rule
:
- List all the base classes, following the classic lookup rule and include a class multiple times if it’s visited repeatedly. In the above example, the list of visited classes is [D, B, A, C, A].
- Scan the list for duplicated classes. If any are found, remove all but one occurrence, leaving the last one in the list. In the above example, the list becomes [D, B, C, A] after dropping duplicates.
m = ['I', 'G', 'D', 'C', 'X', 'object', 'X', 'object', 'B', 'A', 'X', 'object', 'F', 'Y', 'object', 'B', 'A', 'X', 'object'] s = set() custom_mro = [i for i in reversed(m) if not (i in s or s.add(i))][::-1] original_mro = list(i.__name__ for i in I.__mro__) assert custom_mro == original_mro print(custom_mro) #['I', 'G', 'D', 'C', 'F', 'Y', 'B', 'A', 'X', 'object']
Y is printed because Y
class is listed first on the mro order.