pythonpython-3.xmethod-resolution-order

Why does the MRO of this class change when one subclass does/doesnt inherit a third class in Python?


I'm trying to get a better understanding of MRO in Python & came across this example:

  class A:
    def process(self):
        print('A process()')


class B(A):
    pass


class C(A):
    def process(self):
        print('C process()')


class D(B,C):
    pass


obj = D()
obj.process()

which prints "C process()". I understand why, because the order goes D>B>C>A. but, when the class C doesn't inherit A, then "A process()" is printed & the order shifts to D>B>A>C. what causes the order to shift here? why isn't the C superclass reached before the A class now?


Solution

  • The C3 linearization algorithm is somewhat depth-first, so A, being reachable from B (which is listed before C in the base class list) is added before C.

    The rationale is that D is more "B-like" than "C-like", so anything that is part of "B" should appear before "C".

    (For fun, see what happens if you try something like class D(B, A, C) when C still inherits from A.)