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