Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 397
Ishinomori Avatar asked Mar 02 '23 21:03

Ishinomori


1 Answers

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.

like image 108
Raymond Hettinger Avatar answered Mar 11 '23 02:03

Raymond Hettinger