A simplified summary of Python's method resolution order
Crudely summarized, method resolution order is how Python decides where to look for a method (or any other attribute) on a class that inherits from several classes. Python actually has two; a simple one for old style classes and a rather complicated one for new style classes.
(Technically, method resolution order applies even for single inheritance classes, it's just that they have a very boring one.)
With the old style class:
class Foo(A, B, C): pass
Python will look up Foo.foo
by looking for foo
on A and all of its
ancestors, then B and all its ancestors, and finally C and all its
ancestors; that is, the method resolution order is left to right, depth
first.
This order is nice and simple but blows up if A and B have a common
ancestor with behavior that B wants to override, which is why new style
classes need a different scheme. (All new style classes are ultimately
rooted at object
, which defines various default actions for things
like getting and setting attributes.)
The complete description of the method resolution order for new style classes is somewhat complicated. For simple class structures, it can be summarized as left to right and depth first but common ancestor classes are only checked after all of their children have been checked. Thus, with new style classes:
class A1(object): pass class A2(object): pass class A3(object): pass class B2(A2): pass class B3(A3): pass class C3(B3): pass class Foo(C3, A1, B2): pass
The method resolution order for Foo.foo
is Foo, C3, B3, A3, A1, B2,
A2, and then object
; as the common ancestor, object
is checked
only after all of its children have been. Note that the MRO can vary
drastically between a parent and a child class; C3's MRO is just C3, B3,
A3, and object
.
In case of doubt or curiosity you can find the MRO of any new style
class in its __mro__
attribute. Normally you don't need to care
about its value and should use the super()
builtin if you need to find
the next class up in the context of a particular object or class.
(This is the kind of entry I write partly to make sure I have all this straight in my own head.)
|
|