Python / Mixins

Using Python Mixins

By Marcelo Fernandes Sep 3, 2017

Mixins Basics

Mixins are regular classes, that are used in order to work with multiple inheritance, they are commonly used when:

  • 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.

For example, let's say that we are creating a class that is capable of handling requests to our website, the goal of this particular class is to treat the request and send a response:

from mylib import ConcreteRequest

class Request(ConcreteRequest):
    """Do somethings with the request and return a response"""

But this is very generic, if we want only the logged-in users to have access to our requests, what would we do? Probably the first answer is: "We can hardcode it inside the class". But this is a very bad idea, once our project grows bigger and we have more requests to deal with, we will have to hard code it in every single Request Handle class.

Here is where Mixins come in. Whenever we want to specialize a particular class, with something very simple, we use mixins. We must remember some rules for good practices.

  • If a class is designed to provide method implementations for reuse by multiple unrelated subclasses, without implying an "is-a" relationship, it should be an explicit mixin class
  • A mixin does not define a new type, it only make a pack of methods for reuse.
  • A mixin should never be instantiated.
  • Concrete classes should not inherit only from a mixin.
  • Each mixin should provide a single specific behavior, implementing few and very closely related methods.
  • Make mixins explicit by naming. Python has no formal way to state that a class is a mixin, so it's highly recommended that they are named with a ...Mixin suffix.

Keeping that rule in mind, we can specialize our Request class to have a special treatment for logged-in users, and a special treatment for arguments in the request Header, making it inherit from those particular mixins.

from mylib import ConcreteRequest, UserAuthenticatedMixin, ValidateHeaderMixin

class Request(UserAuthenticatedMixin, ValidateHeaderMixin, ConcreteRequest):
    """Do somethings with the request and return a response"""