5.13. OOP Inheritance MRO¶
MRO - Method Resolution Order
Inheritance Diamond
5.13.1. Problem¶
>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
... def __init__(self):
... print('Crew')
>>>
>>>
>>> crew = Crew()
Crew
5.13.2. Small Diamond¶

>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
... pass
>>>
>>>
>>> crew = Crew()
Astronaut
>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
... def __init__(self):
... super().__init__()
>>>
>>>
>>> crew = Crew()
Astronaut

>>> Crew.mro()
[<class '__main__.Crew'>,
<class '__main__.Astronaut'>,
<class '__main__.Cosmonaut'>,
<class '__main__.Person'>,
<class 'object'>]
>>> Crew.__mro__
(<class '__main__.Crew'>,
<class '__main__.Astronaut'>,
<class '__main__.Cosmonaut'>,
<class '__main__.Person'>,
<class 'object'>)
5.13.3. Large Diamond¶

>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
>>>
>>> class VeteranAstronaut(Astronaut):
... def __init__(self):
... print('VeteranAstronaut')
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
>>>
>>> class VeteranCosmonaut(Cosmonaut):
... def __init__(self):
... print('VeteranCosmonaut')
>>>
>>>
>>> class Crew(VeteranAstronaut, VeteranCosmonaut):
... def __init__(self):
... super().__init__()
>>>
>>>
>>> crew = Crew()
VeteranAstronaut
>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
>>>
>>> class VeteranAstronaut(Astronaut):
... def __init__(self):
... super().__init__()
... print('VeteranAstronaut')
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
>>>
>>> class VeteranCosmonaut(Cosmonaut):
... def __init__(self):
... super().__init__()
... print('VeteranCosmonaut')
>>>
>>>
>>> class Crew(VeteranAstronaut, VeteranCosmonaut):
... pass
>>>
>>>
>>> crew = Crew()
Astronaut
VeteranAstronaut
5.13.4. Problematic super()¶
>>> class Person:
... def __init__(self):
... print('Person')
>>>
>>>
>>> class Astronaut(Person):
... def __init__(self):
... print('Astronaut')
... super().__init__()
>>>
>>> class VeteranAstronaut(Astronaut):
... def __init__(self):
... print('VeteranAstronaut')
... super().__init__()
>>>
>>>
>>> class Cosmonaut(Person):
... def __init__(self):
... print('Cosmonaut')
... super().__init__()
>>>
>>> class VeteranCosmonaut(Cosmonaut):
... def __init__(self):
... print('VeteranCosmonaut')
... super().__init__()
>>>
>>>
>>> class Crew(VeteranAstronaut, VeteranCosmonaut):
... pass
>>>
>>>
>>> crew = Crew()
VeteranAstronaut
Astronaut
VeteranCosmonaut
Cosmonaut
Person
5.13.5. Why?!¶
Raymond Hettinger - Super considered super! - PyCon 2015 1

>>> Crew.mro()
[<class '__main__.Crew'>,
<class '__main__.VeteranAstronaut'>,
<class '__main__.Astronaut'>,
<class '__main__.VeteranCosmonaut'>,
<class '__main__.Cosmonaut'>,
<class '__main__.Person'>,
<class 'object'>]
5.13.6. Compare¶
