Ishinomori
Ishinomori

Reputation: 229

Python Method Resolution Order

Could someone explain the output of given code and how python MRO works in this case?

class A(object):
    def go(self):
        print("go A go!")


class B(A):
    def go(self):
        super(B, self).go()
        print("go B go!")


class C(A):
    def go(self):
        super(C, self).go()
        print("go C go!")


class D(C, B):
    def go(self):
        super(D, self).go()
        print("go D go!")


d = D()
d.go()

Output:

go A go!
go B go!
go C go!
go D go!

Following left-to-right and depth I would say it should be:

go A go!
go C go!
go D go!

but seems it dosn't work as I thought.

Upvotes: 4

Views: 313

Answers (1)

Raymond Hettinger
Raymond Hettinger

Reputation: 226336

The MRO for a class is based on the MRO of it parents:

>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

The three rules are:

  1. Children go before parents:
  • A < object
  • B < A
  • C < A
  • D < C
  • D < B
  1. Parents go in the order of bases:
  • C < B
  1. Parent mros are merged, preserving their order.
  • merge B < A < object with C < A < object

In the early days of Python 2, the search rule used to be depth-first-left-ot-right, but that changed based on research into the C3 linearization algorithm.

See the Super Considered Super blog post for ways to take advantage of this algorithm in real code.

Upvotes: 7

Related Questions