Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens if you mix old and new style classes in a hierarchy?

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?

like image 421
Stefano Borini Avatar asked Jun 11 '13 11:06

Stefano Borini


1 Answers

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.

like image 107
Armin Rigo Avatar answered Oct 19 '22 18:10

Armin Rigo