MRO: Understanding Multiple Inheritance in Python

While building a project in Django, it’s common to encounter multiple inheritance. For example, Django’s own ListView class has multiple parent Classes

What is MRO

MRO is Method Resolution Order. It defines the order of functions/methods for Python interpreter to use if there are multiple inheritance.

For example,

class A():
    def who_am_i(self):
        print("This is class A")


class B(A):
    pass


class C(A):
    def who_am_i(self):
        print("This is class C")


class D(B, C):
    pass


d = D()

print(d.who_am_i())

The result is class C

History of MRO in Python

  • Python 2.1: Old-style class, DFS algorithm was used
  • Python 2.2: New-style class was introduced, both DFS and BFS
  • Python 2.3 thru 2.7: New-style and Old-style coexisted, DFS and C3
  • Python 3.x: Only new-style class, C3

Check the MRO order

In new-style class there’s a magic method to check it’s MRO order

print(ListView.__mro__)

result:

(<class 'django.views.generic.list.ListView'>, 
<class 'django.views.generic.list.MultipleObjectTemplateResponseMixin'>, 
<class 'django.views.generic.base.TemplateResponseMixin'>, 
<class 'django.views.generic.list.BaseListView'>, 
<class 'django.views.generic.list.MultipleObjectMixin'>, 
<class 'django.views.generic.base.ContextMixin'>, 
<class 'django.views.generic.base.View'>, 
<class 'object'>)

C3 Algorithms

For a more complex sample

class X():
    def who_am_i(self):
        print("X")

class Y():
    def who_am_i(self):
        print("Y")

class A(X, Y):
    def who_am_i(self):
        print("A")

class B(Y, X):
    def who_am_i(self):
        print("B")

class C(A, B):
    def who_am_i(self):
        print("C")

Here’s an explanation on Wiki


   Reprint policy


《MRO: Understanding Multiple Inheritance in Python》 by Isaac Zhou is licensed under a Creative Commons Attribution 4.0 International License
  TOC