What is a mixin and why is it useful?

419,292

Solution 1

A mixin is a special kind of multiple inheritance. There are two main situations where mixins are used:

  1. You want to provide a lot of optional features for a class.
  2. You want to use one particular feature in a lot of different classes.

For an example of number one, consider werkzeug's request and response system. I can make a plain old request object by saying:

from werkzeug import BaseRequest

class Request(BaseRequest):
    pass

If I want to add accept header support, I would make that

from werkzeug import BaseRequest, AcceptMixin

class Request(AcceptMixin, BaseRequest):
    pass

If I wanted to make a request object that supports accept headers, etags, authentication, and user agent support, I could do this:

from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin

class Request(AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin, BaseRequest):
    pass

The difference is subtle, but in the above examples, the mixin classes weren't made to stand on their own. In more traditional multiple inheritance, the AuthenticationMixin (for example) would probably be something more like Authenticator. That is, the class would probably be designed to stand on its own.

Solution 2

First, you should note that mixins only exist in multiple-inheritance languages. You can't do a mixin in Java or C#.

Basically, a mixin is a stand-alone base type that provides limited functionality and polymorphic resonance for a child class. If you're thinking in C#, think of an interface that you don't have to actually implement because it's already implemented; you just inherit from it and benefit from its functionality.

Mixins are typically narrow in scope and not meant to be extended.

[edit -- as to why:]

I suppose I should address why, since you asked. The big benefit is that you don't have to do it yourself over and over again. In C#, the biggest place where a mixin could benefit might be from the Disposal pattern. Whenever you implement IDisposable, you almost always want to follow the same pattern, but you end up writing and re-writing the same basic code with minor variations. If there were an extendable Disposal mixin, you could save yourself a lot of extra typing.

[edit 2 -- to answer your other questions]

What separates a mixin from multiple inheritance? Is it just a matter of semantics?

Yes. The difference between a mixin and standard multiple inheritance is just a matter of semantics; a class that has multiple inheritance might utilize a mixin as part of that multiple inheritance.

The point of a mixin is to create a type that can be "mixed in" to any other type via inheritance without affecting the inheriting type while still offering some beneficial functionality for that type.

Again, think of an interface that is already implemented.

I personally don't use mixins since I develop primarily in a language that doesn't support them, so I'm having a really difficult time coming up with a decent example that will just supply that "ahah!" moment for you. But I'll try again. I'm going to use an example that's contrived -- most languages already provide the feature in some way or another -- but that will, hopefully, explain how mixins are supposed to be created and used. Here goes:

Suppose you have a type that you want to be able to serialize to and from XML. You want the type to provide a "ToXML" method that returns a string containing an XML fragment with the data values of the type, and a "FromXML" that allows the type to reconstruct its data values from an XML fragment in a string. Again, this is a contrived example, so perhaps you use a file stream, or an XML Writer class from your language's runtime library... whatever. The point is that you want to serialize your object to XML and get a new object back from XML.

The other important point in this example is that you want to do this in a generic way. You don't want to have to implement a "ToXML" and "FromXML" method for every type that you want to serialize, you want some generic means of ensuring that your type will do this and it just works. You want code reuse.

If your language supported it, you could create the XmlSerializable mixin to do your work for you. This type would implement the ToXML and the FromXML methods. It would, using some mechanism that's not important to the example, be capable of gathering all the necessary data from any type that it's mixed in with to build the XML fragment returned by ToXML and it would be equally capable of restoring that data when FromXML is called.

And.. that's it. To use it, you would have any type that needs to be serialized to XML inherit from XmlSerializable. Whenever you needed to serialize or deserialize that type, you would simply call ToXML or FromXML. In fact, since XmlSerializable is a fully-fledged type and polymorphic, you could conceivably build a document serializer that doesn't know anything about your original type, accepting only, say, an array of XmlSerializable types.

Now imagine using this scenario for other things, like creating a mixin that ensures that every class that mixes it in logs every method call, or a mixin that provides transactionality to the type that mixes it in. The list can go on and on.

If you just think of a mixin as a small base type designed to add a small amount of functionality to a type without otherwise affecting that type, then you're golden.

Hopefully. :)

Solution 3

This answer aims to explain mixins with examples that are:

  • self-contained: short, with no need to know any libraries to understand the example.

  • in Python, not in other languages.

    It is understandable that there were examples from other languages such as Ruby since the term is much more common in those languages, but this is a Python thread.

It shall also consider the controversial question:

Is multiple inheritance necessary or not to characterize a mixin?

Definitions

I have yet to see a citation from an "authoritative" source clearly saying what is a mixin in Python.

I have seen 2 possible definitions of a mixin (if they are to be considered as different from other similar concepts such as abstract base classes), and people don't entirely agree on which one is correct.

The consensus may vary between different languages.

Definition 1: no multiple inheritance

A mixin is a class such that some method of the class uses a method which is not defined in the class.

Therefore the class is not meant to be instantiated, but rather serve as a base class. Otherwise the instance would have methods that cannot be called without raising an exception.

A constraint which some sources add is that the class may not contain data, only methods, but I don't see why this is necessary. In practice however, many useful mixins don't have any data, and base classes without data are simpler to use.

A classic example is the implementation of all comparison operators from only <= and ==:

class ComparableMixin(object):
    """This class has methods which use `<=` and `==`,
    but this class does NOT implement those methods."""
    def __ne__(self, other):
        return not (self == other)
    def __lt__(self, other):
        return self <= other and (self != other)
    def __gt__(self, other):
        return not self <= other
    def __ge__(self, other):
        return self == other or self > other

class Integer(ComparableMixin):
    def __init__(self, i):
        self.i = i
    def __le__(self, other):
        return self.i <= other.i
    def __eq__(self, other):
        return self.i == other.i

assert Integer(0) <  Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) >  Integer(0)
assert Integer(1) >= Integer(1)

# It is possible to instantiate a mixin:
o = ComparableMixin()
# but one of its methods raise an exception:
#o != o 

This particular example could have been achieved via the functools.total_ordering() decorator, but the game here was to reinvent the wheel:

import functools

@functools.total_ordering
class Integer(object):
    def __init__(self, i):
        self.i = i
    def __le__(self, other):
        return self.i <= other.i
    def __eq__(self, other):
        return self.i == other.i

assert Integer(0) < Integer(1)
assert Integer(0) != Integer(1)
assert Integer(1) > Integer(0)
assert Integer(1) >= Integer(1)

Definition 2: multiple inheritance

A mixin is a design pattern in which some method of a base class uses a method it does not define, and that method is meant to be implemented by another base class, not by the derived like in Definition 1.

The term mixin class refers to base classes which are intended to be used in that design pattern (TODO those that use the method, or those that implement it?)

It is not easy to decide if a given class is a mixin or not: the method could be just implemented on the derived class, in which case we're back to Definition 1. You have to consider the author's intentions.

This pattern is interesting because it is possible to recombine functionalities with different choices of base classes:

class HasMethod1(object):
    def method(self):
        return 1

class HasMethod2(object):
    def method(self):
        return 2

class UsesMethod10(object):
    def usesMethod(self):
        return self.method() + 10

class UsesMethod20(object):
    def usesMethod(self):
        return self.method() + 20

class C1_10(HasMethod1, UsesMethod10): pass
class C1_20(HasMethod1, UsesMethod20): pass
class C2_10(HasMethod2, UsesMethod10): pass
class C2_20(HasMethod2, UsesMethod20): pass

assert C1_10().usesMethod() == 11
assert C1_20().usesMethod() == 21
assert C2_10().usesMethod() == 12
assert C2_20().usesMethod() == 22

# Nothing prevents implementing the method
# on the base class like in Definition 1:

class C3_10(UsesMethod10):
    def method(self):
        return 3

assert C3_10().usesMethod() == 13

Authoritative Python occurrences

At the official documentatiton for collections.abc the documentation explicitly uses the term Mixin Methods.

It states that if a class:

  • implements __next__
  • inherits from a single class Iterator

then the class gets an __iter__ mixin method for free.

Therefore at least on this point of the documentation, mixin does not not require multiple inheritance, and is coherent with Definition 1.

The documentation could of course be contradictory at different points, and other important Python libraries might be using the other definition in their documentation.

This page also uses the term Set mixin, which clearly suggests that classes like Set and Iterator can be called Mixin classes.

In other languages

  • Ruby: Clearly does not require multiple inheritance for mixin, as mentioned in major reference books such as Programming Ruby and The Ruby programming Language

  • C++: A virtual method that is set =0 is a pure virtual method.

    Definition 1 coincides with the definition of an abstract class (a class that has a pure virtual method). That class cannot be instantiated.

    Definition 2 is possible with virtual inheritance: Multiple Inheritance from two derived classes

Solution 4

I think of them as a disciplined way of using multiple inheritance - because ultimately a mixin is just another python class that (might) follow the conventions about classes that are called mixins.

My understanding of the conventions that govern something you would call a Mixin are that a Mixin:

  • adds methods but not instance variables (class constants are OK)
  • only inherits from object (in Python)

That way it limits the potential complexity of multiple inheritance, and makes it reasonably easy to track the flow of your program by limiting where you have to look (compared to full multiple inheritance). They are similar to ruby modules.

If I want to add instance variables (with more flexibility than allowed for by single inheritance) then I tend to go for composition.

Having said that, I have seen classes called XYZMixin that do have instance variables.

Solution 5

What separates a mixin from multiple inheritance? Is it just a matter of semantics?

A mixin is a limited form of multiple inheritance. In some languages the mechanism for adding a mixin to a class is slightly different (in terms of syntax) from that of inheritance.

In the context of Python especially, a mixin is a parent class that provides functionality to subclasses but is not intended to be instantiated itself.

What might cause you to say, "that's just multiple inheritance, not really a mixin" is if the class that might be confused for a mixin can actually be instantiated and used - so indeed it is a semantic, and very real, difference.

Example of Multiple Inheritance

This example, from the documentation, is an OrderedCounter:

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first encountered'

     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

It subclasses both the Counter and the OrderedDict from the collections module.

Both Counter and OrderedDict are intended to be instantiated and used on their own. However, by subclassing them both, we can have a counter that is ordered and reuses the code in each object.

This is a powerful way to reuse code, but it can also be problematic. If it turns out there's a bug in one of the objects, fixing it without care could create a bug in the subclass.

Example of a Mixin

Mixins are usually promoted as the way to get code reuse without potential coupling issues that cooperative multiple inheritance, like the OrderedCounter, could have. When you use mixins, you use functionality that isn't as tightly coupled to the data.

Unlike the example above, a mixin is not intended to be used on its own. It provides new or different functionality.

For example, the standard library has a couple of mixins in the socketserver library.

Forking and threading versions of each type of server can be created using these mix-in classes. For instance, ThreadingUDPServer is created as follows:

class ThreadingUDPServer(ThreadingMixIn, UDPServer):
    pass

The mix-in class comes first, since it overrides a method defined in UDPServer. Setting the various attributes also changes the behavior of the underlying server mechanism.

In this case, the mixin methods override the methods in the UDPServer object definition to allow for concurrency.

The overridden method appears to be process_request and it also provides another method, process_request_thread. Here it is from the source code:

class ThreadingMixIn:
        """Mix-in class to handle each request in a new thread."""

        # Decides how threads will act upon termination of the
        # main process
        daemon_threads = False

        def process_request_thread(self, request, client_address):
            """Same as in BaseServer but as a thread.
            In addition, exception handling is done here.
            """
            try:
                self.finish_request(request, client_address)
            except Exception:
                self.handle_error(request, client_address)
            finally:
                self.shutdown_request(request)

        def process_request(self, request, client_address):
            """Start a new thread to process the request."""
            t = threading.Thread(target = self.process_request_thread,
                                 args = (request, client_address))
            t.daemon = self.daemon_threads
            t.start()

A Contrived Example

This is a mixin that is mostly for demonstration purposes - most objects will evolve beyond the usefulness of this repr:

class SimpleInitReprMixin(object):
    """mixin, don't instantiate - useful for classes instantiable
    by keyword arguments to their __init__ method.
    """
    __slots__ = () # allow subclasses to use __slots__ to prevent __dict__
    def __repr__(self):
        kwarg_strings = []
        d = getattr(self, '__dict__', None)
        if d is not None:
            for k, v in d.items():
                kwarg_strings.append('{k}={v}'.format(k=k, v=repr(v)))
        slots = getattr(self, '__slots__', None)
        if slots is not None:
            for k in slots:
                v = getattr(self, k, None)
                kwarg_strings.append('{k}={v}'.format(k=k, v=repr(v)))
        return '{name}({kwargs})'.format(
          name=type(self).__name__,
          kwargs=', '.join(kwarg_strings)
          )

and usage would be:

class Foo(SimpleInitReprMixin): # add other mixins and/or extend another class here
    __slots__ = 'foo',
    def __init__(self, foo=None):
        self.foo = foo
        super(Foo, self).__init__()

And usage:

>>> f1 = Foo('bar')
>>> f2 = Foo()
>>> f1
Foo(foo='bar')
>>> f2
Foo(foo=None)
Share:
419,292
TarkaDaal
Author by

TarkaDaal

I program professionally, and I try to know what I'm doing. "Try" being the operative word.

Updated on August 05, 2022

Comments

  • TarkaDaal
    TarkaDaal almost 2 years

    In Programming Python, Mark Lutz mentions the term mixin. I am from a C/C++/C# background and I have not heard the term before. What is a mixin?

    Reading between the lines of this example (which I have linked to because it is quite long), I am presuming it is a case of using multiple inheritance to extend a class as opposed to proper subclassing. Is this right?

    Why would I want to do that rather than put the new functionality into a subclass? For that matter, why would a mixin/multiple inheritance approach be better than using composition?

    What separates a mixin from multiple inheritance? Is it just a matter of semantics?

  • Keltia
    Keltia over 15 years
    I disagree slightly on your first sentence. Ruby is a single-inheritance language and mixins are the way to add methods to a given class w/o inherite from another class.
  • dss539
    dss539 about 15 years
    "First, you should note that mixins only exist in multiple-inheritance languages. You can't do a mixin in Java or C#." C# 3.0 added extension methods which do allow you to "sort of" use mixins in C#. See stackoverflow.com/questions/783312/…
  • helloworlder
    helloworlder over 14 years
    With the XML example, isn't it possible to just have a class called XMLSerializer that the client class has a reference to?
  • Randolpho
    Randolpho over 14 years
    @helloworlder: Yes, you could. That wouldn't be a mixin, however. Again, I was trying to use a contrived example of a mixin, not trying to specify best-practice for XML serialization.
  • Lee B
    Lee B about 14 years
    Mixin is a general term, used in D, Ruby, etc. According to Wikipedia, they originated in old school lisp systems, and were first documented in 1983: en.wikipedia.org/wiki/…
  • webwurst
    webwurst over 12 years
    Since Version 2.3 Python uses the "C3 method resolution" explained in The Python 2.3 Method Resolution Order or Method Resolution Order.
  • Tobias Kienzler
    Tobias Kienzler about 11 years
    Here's a post providing a similar mixin for Python. Though the suggestion is defining __lt__ as base instead of __cmp__, the latter of which is actually deprecated and discouraged to use. To me it seems simpler to use that mixin instead of quite complicated decorators (part of functools) - although this one may be able to react more dynamically on which comparisons are provided...
  • tdammers
    tdammers about 11 years
    @Randolpho: so how would one tell the difference between something being a mixin (Python), and something just looking like one (C#)? AFAIK, the most striking difference is that C# enforces certain type-related rules when you implement extension methods, but that's consistent with a statically-typed type-strict language.
  • Randolpho
    Randolpho about 11 years
    @tdammers The difference is that a mixin uses inheritance. Anything that doesn't use inheritance isn't a mixin. Extension methods may use syntactic sugar to look like instance methods on a type, but they're not done via inheritance. An extension method does not have access to protected members (at least, not without reflection), nor is there polymorphism against the mixed in type.
  • tdammers
    tdammers about 11 years
    @Randolpho: but then, there is no such thing as 'protected members' in Python anyway. But you're right, mixins are semantically different from extension methods (actual multiple inheritance vs. syntactically sugared static functions).
  • tdammers
    tdammers about 11 years
    Personally, I'd take mixins over monkey-patching in most cases; it's easier to reason about and follow through the code.
  • Trevor
    Trevor about 11 years
    Actually, a true mixin can't use multiple inheritance. A mixin includes methods, attributes, etc. from one class in another without inheriting it. This tends to give the benefits of code reuse seem with polymorphism but leaves out the problems determining parentage (the diamond of death, etc.) Mixin supporting languages also tend to allow partial inclusion of the mixin class (things are starting to sound a bit like aspects now).
  • Randolpho
    Randolpho almost 11 years
    @offby1 heh, no, I definitely meant poly morphic resonance. :)
  • bootchk
    bootchk almost 11 years
    A third situation is: you want to provide a lot of (not-optional) features for a class, but you want the features in separate classes (and in separate modules) so each module is about one feature (behaviour.) IOW, not for re-use, but for compartmentalization.
  • Ryan B. Lynch
    Ryan B. Lynch almost 11 years
    Downvoted. While your answer expresses a valid opinion of development styles, you don't really address the actual question.
  • Seng Cheong
    Seng Cheong over 10 years
    "The point of a mixin is to create a type that can be "mixed in" to any other type via inheritance without affecting the inheriting type while still offering some beneficial functionality for that type." I think this is a perfect summary - really helped me understand when to use mixins.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com over 10 years
    What is the difference between this and multiple inheritance in general?
  • ka8725
    ka8725 over 10 years
    The difference is that you are not able to create instances from modules, but if there is no differentiation between general classes and modules the mixins is not explicit thing and it stands to hard to understand where is a general class and where is a mixin
  • huggie
    huggie over 10 years
    How is the XML serialization example "contrived"? It looks like a good use case to me. Is it because most XML serialization method are already there and not implemented with mixin?
  • Randolpho
    Randolpho over 10 years
    @huggie basically yes. XML serialization is a solved problem, there's no real need to reinvent the wheel with a mixin. I was just searching for a way to explain the concept using concepts most people would understand.
  • Trilarion
    Trilarion about 10 years
    So in Ruby mixins are just classes that cannot be instantiated but must be used for multiple inheritance?
  • Trilarion
    Trilarion about 10 years
    Btw. in Java the closest thing to a Mixin would be an abstract implementation of an interface like AbstractTableModel, ... Only with the absence of multiple inheritance they obviously favor composition.
  • hillel
    hillel about 10 years
    Probably not an issue in this example, but you generally want to put the main base class as the last element within the parenthesis so to create the inheritance chain: Request==>Mixin==>...==>BaseRequest. See here: ianlewis.org/en/mixins-and-python
  • DejanLekic
    DejanLekic about 9 years
    D is a single-inheritance language, and has two forms of mixins. One, which is close to Python mixins is the D "template mixin". Another form is a string mixin, which allows developer to generate valid D code, and mix it in the current code. More on dlang.org
  • Eliseu Monar dos Santos
    Eliseu Monar dos Santos about 9 years
    @hillel good point, but keep in mind that Python will call superclasses' methods from left to right (when you need to override the constructor, for example).
  • shmosel
    shmosel almost 9 years
    For the record, Java now supports mixins with default methods.
  • Varun Gupta
    Varun Gupta over 8 years
    Brilliant explanation
  • Ishan Bhatt
    Ishan Bhatt almost 8 years
    " If you're thinking in C#, think of an interface that you don't have to actually implement because it's already implemented; you just inherit from it and benefit from its functionality." Is it like Marker Interface like Serializable or Clonable???
  • ashrasmun
    ashrasmun over 5 years
    Mixins and CRTP are not exacly the same thing in C++.
  • Maggyero
    Maggyero over 2 years
    ‘This page also uses the term Set mixin, which clearly suggests that classes like Set and Iterator can be called Mixin classes.’ So doesn’t it contradict your mixin class definition 1 which requires mixin classes to use methods that they do not define, since Iterator violates that requirement (cf. its implementation)?
  • Gwang-Jin Kim
    Gwang-Jin Kim about 2 years
    Thank you! That comparison makes it much clearer!
  • Osman-pasha
    Osman-pasha about 2 years
    This doesn't actually explain what a mixin is and how it is different from an ordinary class that also can be multiple-inherited