Question

Suppose you have something like

class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass

How does python behave relative to inheritance and method resolution order when you have a mixed hierarchy? Does it obey the old traversal, the new traversal, a mix of the two depending on which branch of the hierarchy is walking?

Was it helpful?

Solution

The answer is "a mix of the two". You can check yourself by using inspect.getmro(), which works on both old-style and new-style classes. It returns the MRO, i.e. the method resolution order.

Any old-style class has a MRO that is depth-first, first-to-last-base. (This is a bad idea for the most complicated cases, but kept as backward compatibility.) We can express it like this, which works because the MRO of all parent classes has already been computed:

 mro(new_class) = [new_class] + mro(first_base) + mro(second_base) + ...

For new-style classes, the algorithm uses the same basic idea, but is more complicated --- it also starts with [new_class] but is followed by some more clever merge of the lists mro(first_base), mro(second_base), etc.

Whether each of these base classes are old-style or new-style, they already have their own MRO computed earlier, and these MROs (as lists) are the only thing used to compute the MRO of the new class.

OTHER TIPS

From docs:

the linearization of C is the sum of C plus the merge of the linearizations of the parents and the list of the parents.

That would mean that it depends on which branch of the hierarchy it is currently walking (i.e. it's a mix).

It has to be done recursively so I would not expect different behaviour.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top