Multiple Inheritance &
Mixins

Recap

  • inheritance/OOP
  • super()
  • __dunders__
  • Name mangling
  • setattr / getattr
  • @classmethod / @staticmethod
  • git & GitHub

Multiple Inheritance

Basic example

class Soul:
    def __init__(self):
        print('Spirit...')


class Body:
    def __init__(self):
        print('Physics...')

class Human1(Soul, Body):
    def __init__(self):
        super().__init__()


me = Human1()  # 'Spirit...'
class Human2(Body, Soul):
    def __init__(self):
        super().__init__()


other_me = Human2()  # 'Physics...'

Going deeper in inheritance

  • MRO (Method Resolution Order)
  • Python uses C3 Linearization to build it's MRO
    • C3 ensures monotonicity
  • If a class inherits from multiple classes, they are kept in the order specified in the tuple of the base class.
  • super() refers to the next class from the MRO
  • SomeClass.mro()
  • dir(obj)

MRO example

class F: pass


class E: pass


class D: pass


class C(D, F): pass


class B(D, E): pass


class A(B, C): pass

from pprint import pprint
pprint(A.mro())
[<class '__main__.A'>,
 <class '__main__.B'>,
 <class '__main__.C'>,
 <class '__main__.D'>,
 <class '__main__.E'>,
 <class '__main__.F'>,
 <class 'object'>]

Understanding monotonicity

class A: pass


class B: pass


class C(A, B) : pass


class D(B, A): pass


class E(C, D): pass

print(E.mro())
Traceback (most recent call last):
  File "demo.py", line 13, in <module>
    class E(C,D): pass
TypeError: Cannot create a consistent method resolution
order (MRO) for bases A, B

An MRO is said to be monotonic if C1 precedes C2 in the linearization of C, then C1 precedes C2 in the linearization of any subclass of C.

Mixins conception

  • Another level of abstraction
  • Python's "interfaces"
  • Why should I use it?
    • You want to provide a lot of optional features for a class.
    • You want to use one particular feature in a lot of different classes.
  • Mixins are usually described as being included rather than being inherited
class UserListView(
  WithAuthentication,  # mixin
  WithHandleExceptions,  # mixin
  BaseListView  # not mixin
):
    pass

locals() and globals()

  • globals() - gives you a dictionary representation of the current module namespace
  • locals() - gives you a dictionary representation of the current namespace

Pyhon 101 9th Mixins

By Hack Bulgaria

Pyhon 101 9th Mixins

  • 951