5.8. OOP Method Resolution Order

5.8.1. Recap

>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     pass
>>>
>>>
>>> astro = Astronaut()
Person init
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>>
>>> astro = Astronaut()
Astronaut init
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         super().__init__()
...         print('Astronaut init')
>>>
>>>
>>> astro = Astronaut()
Person init
Astronaut init
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
...         super().__init__()
>>>
>>>
>>> a = Astronaut()
Astronaut init
Person init

5.8.2. Inheritance Diamond

../../_images/oop-mro-diamond-both-empty.png
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>>
>>> class Cosmonaut(Person):
...     def __init__(self):
...         print('Cosmonaut init')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
...     def __init__(self):
...         print('Crew init')
>>>
>>>
>>> crew = Crew()
Crew init

5.8.3. Small Diamond

../../_images/oop-mro-diamond-small-empty.png
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>>
>>> class Cosmonaut(Person):
...     def __init__(self):
...         print('Cosmonaut init')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
...     pass
>>>
>>>
>>> crew = Crew()
Astronaut init
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>>
>>> class Cosmonaut(Person):
...     def __init__(self):
...         print('Cosmonaut init')
>>>
>>>
>>> class Crew(Astronaut, Cosmonaut):
...     def __init__(self):
...         super().__init__()
>>>
>>>
>>> crew = Crew()
Astronaut init
../../_images/oop-mro-diamond-small-path.png
>>> Crew.mro()  
[<class 'Crew'>,
 <class 'Astronaut'>,
 <class 'Cosmonaut'>,
 <class 'Person'>,
 <class 'object'>]
>>> Crew.__mro__  
(<class 'Crew'>,
 <class 'Astronaut'>,
 <class 'Cosmonaut'>,
 <class 'Person'>,
 <class 'object'>)

5.8.4. Large Diamond

../../_images/oop-mro-diamond-large-empty.png
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>> class VeteranAstronaut(Astronaut):
...     def __init__(self):
...         print('VeteranAstronaut init')
>>>
>>>
>>> class Cosmonaut(Person):
...     def __init__(self):
...         print('Cosmonaut init')
>>>
>>> class VeteranCosmonaut(Cosmonaut):
...     def __init__(self):
...         print('VeteranCosmonaut init')
>>>
>>>
>>> class Crew(VeteranAstronaut, VeteranCosmonaut):
...     def __init__(self):
...         super().__init__()
>>>
>>>
>>> crew = Crew()
VeteranAstronaut init
>>> class Person:
...     def __init__(self):
...         print('Person init')
>>>
>>>
>>> class Astronaut(Person):
...     def __init__(self):
...         print('Astronaut init')
>>>
>>> class VeteranAstronaut(Astronaut):
...     def __init__(self):
...         super().__init__()
...         print('VeteranAstronaut init')
>>>
>>>
>>> class Cosmonaut(Person):
...     def __init__(self):
...         print('Cosmonaut init')
>>>
>>> class VeteranCosmonaut(Cosmonaut):
...     def __init__(self):
...         super().__init__()
...         print('VeteranCosmonaut init')
>>>
>>>
>>> class Crew(VeteranAstronaut, VeteranCosmonaut):
...     pass
>>>
>>>
>>> crew = Crew()
Astronaut init
VeteranAstronaut init

5.8.5. Problematic super()

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

5.8.6. Why?!

  • Raymond Hettinger - Super considered super! - PyCon 2015 1

../../_images/oop-mro-diamond-large-path.png
>>> Crew.mro()  
[<class 'Crew'>,
 <class 'VeteranAstronaut'>,
 <class 'Astronaut'>,
 <class 'VeteranCosmonaut'>,
 <class 'Cosmonaut'>,
 <class 'Person'>,
 <class 'object'>]

5.8.7. Compare

../../_images/oop-mro-diamond-both-path.png

5.8.8. References

1

https://www.youtube.com/watch?v=EiOglTERPEo

5.8.9. Assignments