Mixin mode is a mode often used in python. Appropriate and reasonable application can achieve the purpose of reusing code and reasonably organizing the code structure.
Python’s Mixin mode can be implemented through multiple inheritance. For example, we customize a simple data container with a nested structure:
class SimpleItemContainer(object): def __init__(self, id, item_containers): self.id = id self.data = {} for item in item_containers: self.data[item.id] = item
SimpleItemContainer uses Python's built-in type Dict to store data. However, so far, if you want to access the corresponding data, you still have to directly call the dictionary inside. You cannot access the data through the exposed API as conveniently as the native dictionary. Of course, you can also implement the complete Dictionary Interface from scratch, but it will definitely not work to have a set in each customized similar container. At this time, using python's built-in UserDict.DictMixin is a good way:
from UserDict import DictMixin
class BetterSimpleItemContainer(object, DictMixin): def __getitem__(self, id): return self.data[id] def __setitem__(self, id, value): self.data[id] = value def __delitem__(self, id): del self.data[id] def keys(self): return self.data.keys()
By implementing the smallest Dictionary Interface and inheriting DictMixin to implement Mixin mode, we can easily obtain the complete native dictionary behavior: the syntax in the following table, get, has_keys, iteritems, itervalues and even iterable protocol implementation, etc. methods and implementation.
Mixin is commonly used in many frameworks such as Django and Django rest framework. When defining api or viewset, you can take advantage of some functions through multiple inheritance
Of course, Mixin mode cannot be abused, at least it will pollute your newly defined classes, and sometimes it will cause MRO problems; but put some basic and single functions, such as functions that are generally expected to be implemented through interface/protocol, into It is still a good choice to enter the Mixin module:
class CommonEqualityMixin(object): def __eq__(self, other): return (isinstance(other, self.__class__) and self.__dict__ == other.__dict__) def __ne__(self, other): return not self.__eq__(other) class Foo(CommonEqualityMixin): def __init__(self, item): self.item = item
In fact, the whole understanding is nothing more than obtaining more functions through combination. It is a bit like the interface in C# and Java, which emphasizes the meaning of "it can", but it is much simpler in comparison and does not require display constraints. And the mixin module comes with its own implementation. When using it, the mixin class is generally placed to the right of the parent class, which seems to emphasize that this is not a typical multiple inheritance, but a special kind of multiple inheritance, but on the basis of inheriting a base class, and incidentally using multiple inheritance. Inherited functions add some flavor to this subclass and add some other functionality. Ensure that Mixin's class functions are single and specific. After mixing, the MRO tree of the new class will actually be relatively simple and will not cause confusion.