Problem
Mark Lutz describes “mixins” in his book “Programming Python.” I’m a C/C++/C# programmer who has never heard of the term. What exactly is a mixin?
Reading between the lines of this example (which I’ve linked to because it’s pretty long), it appears that multiple inheritance is being used to extend a class rather than ‘real’ subclassing. Is this correct?
Why would I want to do that rather than create a subclass for the new functionality? Why would utilizing composition be preferable to using a mixin/multiple inheritance approach?
What is the difference between a mixin and multiple inheritance? Is it merely a question of semantics?
Asked by TarkaDaal
Solution #1
A mixin is a type of multiple inheritance that is unique. Mixins are typically employed in one of two scenarios:
Consider werkzeug’s request and response mechanism as an example of number one. I can create a basic request object by typing:
from werkzeug import BaseRequest
class Request(BaseRequest):
pass
If I wanted to add support for accept headers, I’d do so.
from werkzeug import BaseRequest, AcceptMixin
class Request(AcceptMixin, BaseRequest):
pass
I could do the following to create a request object that supports accept headers, etags, authentication, and user agent support:
from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin
class Request(AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthenticationMixin, BaseRequest):
pass
The distinction is slight, but the mixin classes in the preceding instances were not designed to stand on their own. AuthenticationMixin (for example) would probably be something like Authenticator in more classic multiple inheritance. That is, the class would most likely be designed to function independently.
Answered by Jason Baker
Solution #2
To begin, you should be aware that mixins are only available in languages with multiple inheritance. A mixin is not possible in Java or C#.
A mixin is a stand-alone base type for a child class that provides restricted functionality and polymorphic resonance. If you’re thinking in C#, consider an interface that you don’t have to create since it already exists; you simply inherit from it and get the benefits of its functionality.
Mixins are usually limited in scope and are not intended to be extended.
[edit โ to clarify:]
The advantage is that you won’t have to do it over and over again. The Disposal pattern in C# may be the most important place where a mixin might help. You nearly always want to follow the same pattern while implementing IDisposable, yet you end up writing and re-writing the same fundamental code with slight differences. You could save a lot of typing time if there was an extensible Disposal mixin.
[edit 2 โ to respond to your other inquiries]
Yes. The distinction between a mixin and ordinary multiple inheritance is purely semantic; a class with multiple inheritance might use a mixin as part of that inheritance.
A mixin is a type that may be “mixed in” to any other type via inheritance without changing the inherited type while still providing useful functionality to that type.
Consider an interface that has already been implemented.
I don’t utilize mixins because I create in a language that doesn’t support them, thus I’m having a hard time coming up with a good example that will simply provide you with that “aha!” moment. But I’ll give it another shot. I’ll use a contrived example โ most languages already have the functionality in some form or another โ but it should demonstrate how mixins are designed to be produced and utilized. Here’s how it goes:
Let’s say you have a type that needs to be serialized 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.
Another crucial element to remember in this example is that you want to approach it in a generic manner. You don’t want to have to implement a “ToXML” and “FromXML” function for each type you wish to serialize; instead, you want a generic way to guarantee that your type will do so and that it will work. You wish to reuse code.
If your language supported it, you could create the XmlSerializable mixin to do your work for you. The ToXML and FromXML methods would be implemented by this type. 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.
That’s all there is to it. Any type that has to be serialized to XML should inherit from XmlSerializable to use it. You would just call ToXML or FromXML whenever you needed to serialize or deserialize that type. In reality, because XmlSerializable is a full-fledged type with polymorphism, you could make a document serializer that doesn’t know anything about your original type and only accepts an array of XmlSerializable types.
Consider how you could use this scenario to create a mixin that assures that every class that uses it logs every method call, or a mixin that gives transactionality to the type that uses it. The list could go on indefinitely.
If you conceive of a mixin as a little base type that adds a small amount of functionality to a type without changing it in any way, you’ll be OK.
Hopefully. ๐
Answered by Randolpho
Solution #3
This answer seeks to explain mixins using the following examples:
It will also address the contentious issue of:
Definitions
I have yet to come across a citation from a “authoritative” source that defines a mixin in Python.
Similar notions, such as abstract base classes), are debated, and no one knows which is accurate.
Various languages may have different levels of agreement.
No multiple inheritance (definition 1)
A mixin is a class in which one of its methods calls a method that isn’t declared in the class.
As a result, the class is intended to act as a base class rather than being instantiated. Otherwise, the instance’s methods would not be able to be invoked without throwing an exception.
Some sources add the restriction that the class can only include methods and not data, but I don’t understand why this is required. In practice, however, many important mixins are data-free, and data-free base classes are easier 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
The functools.total ordering() decorator might have been used for this example, but the goal 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)
Multiple inheritance (definition 2)
A mixin is a design pattern in which a base class’s method calls a method that it doesn’t define, and that method is intended to be implemented by another base class rather than the derived, as 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’s not always clear whether a class is a mixin: the function could just be implemented on the derived class, in which case we’re back at Definition 1. You must think about the author’s intentions.
This method is appealing because it allows for the recombination of capabilities using several 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
The phrase Mixin Methods is used directly in the official documentation for collections.abc.
It states that if a class meets the following criteria:
The class then receives a free __iter__ mixin method.
As a result, mixin does not require multiple inheritance, at least according to this section of the documentation, and is consistent with Definition 1.
Of course, the documentation may be conflicting at times, and other significant Python libraries may use the opposite term 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
Answered by Ciro Santilli ๆฐ็ๅๆ่ฒ่ฅๅ ญๅไบไปถๆณ่ฝฎๅ้ๆตทไธ
Solution #4
Because a mixin is merely another python class that (could) obey the standards concerning classes called mixins, I conceive of them as a disciplined approach of employing multiple inheritance.
According to my understanding of the conventions that govern something called a Mixin, a Mixin:
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’re a lot like Ruby modules.
When I wish to add instance variables (with greater flexibility than single inheritance allows), I usually use composition.
Having said that, I’ve seen instances variables in classes like XYZMixin.
Answered by Hamish Downer
Solution #5
A mixin is a type of multiple inheritance that is restricted. In some languages, the technique for adding a mixin to a class differs differently from inheritance in terms of syntax.
A mixin, in the context of Python, is a parent class that offers functionality to subclasses but is not intended to be instantiated.
What may lead you to conclude that “that’s simply multiple inheritance, not really a mixin” is whether the class that could be mistaken for a mixin can be instantiated and utilized – indicating that there is a semantic, and very real, distinction.
This is an OrderedCounter, according to the documentation:
It inherits from the collections module’s Counter and OrderedDict subclasses.
Counter and OrderedDict are designed to be instantiated and used independently. However, by subclassing both of them, we can create an ordered counter that reuses the code from each object.
This is an effective method for reusing code, but it can also be problematic. If one of the objects turns out to have a bug, repairing it carelessly could result in an issue in the subclass.
Mixins are sometimes marketed as a means to reuse code without the potential coupling difficulties that cooperative multiple inheritance, such as the OrderedCounter, can cause. You employ functionality that isn’t as tightly tied to the data when you use mixins.
A mixin, unlike the example above, is not meant to be used on its own. It adds new or different features to the system.
The socketserver library, for example, has a few of mixins from the standard library.
To allow for concurrency, the mixin methods override the methods defined in the UDPServer object description.
Process request appears to be the overridden method, and it also gives another method, process request thread. Here’s what the source code says:
Most objects will evolve beyond the utility of this repr: This is a mixin that is largely for demonstration purposes:
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 its application 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)
Answered by Aaron Hall
Post is based on https://stackoverflow.com/questions/533631/what-is-a-mixin-and-why-are-they-useful