What does "mro()" do?
Follow along...:
>>> class A(object): pass
...
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
...
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
...
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>>
As long as we have single inheritance, __mro__
is just the tuple of: the class, its base, its base's base, and so on up to object
(only works for new-style classes of course).
Now, with multiple inheritance...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
...you also get the assurance that, in __mro__
, no class is duplicated, and no class comes after its ancestors, save that classes that first enter at the same level of multiple inheritance (like B and C in this example) are in the __mro__
left to right.
Every attribute you get on a class's instance, not just methods, is conceptually looked up along the __mro__
, so, if more than one class among the ancestors defines that name, this tells you where the attribute will be found -- in the first class in the __mro__
that defines that name.
mro()
stands for Method Resolution Order. It returns a list of types the class is derived from, in the order they are searched for methods.
mro()
and __mro__
work only on new style classes. In Python 3, they work without any issues. In Python 2, however, those classes need to inherit from object
.