折腾edX和Django Rest Framework的时候都看到Mixin的身影,决定弄清楚它。

##解释 Mixin即mix in,就是混入的意思。在不改变原对象的情况下对其进行扩展. 在运行期间,动态改变类的基类或类的方法
利用Mixin我们还可以增加无数总特征,而无需对已有代码作太大改动。实现无痛扩展

多重继承类似.

但通常主类和 Mixin 类本身不是 is-a 的关系,混入 Mixin 类是为了添加某些(可选的)功能。自由地混入 Mixin 类就可以灵活地为被混入的类添加不同的功能。

传统的「接口」概念中并不包含实现,而 Mixin 包含实现。Mixin 提供了(默认)实现

wu:是为了额外获得方法?

Mixin的好处是可以为主类添加任意多的Mixin来实现多态

##QuickStart

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Fruit(object):
       pass
class GiftMixin(object):
       def is_gift_fruit(self):
              return True
class NotGiftMixin(object):
       def is_gift_fruit(self):
              return False
class PareMixin(object):
       def eat_method(self):
              return 'Pare'
class HuskMixin(object):
       def eat_method(self):
              return 'Husk'
class Apple(GiftMixin, PareMixin, Fruit):pass
class Orange(GiftMixin, HuskMixin, Fruit):pass
class Pear(NotGiftMixin, PareMixin, Fruit):pass
class Banana(NotGiftMixin, HuskMixin, Fruit):pass

这样水果就知道自己的种类和特性啦

##何时用 There are two main situations where mixins are used:

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

摘自what-is-a-mixin-and-why-are-they-useful这篇回答,就是说当一个功能特性被很多个类用到时,或者一个类需要很多功能特性时

##demo ###werkzeug中Request / Response 答主随后举了werkzeug中Request / Response的例子

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

1
2
3
4
from werkzeug import BaseRequest, AcceptMixin, ETagRequestMixin, UserAgentMixin, AuthorizationMixin

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

###django-rest-framework.org/tutorial/3 许多公共行为在REST framework’s mixin类中都实现了.方便的组合与重用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import mixins
from rest_framework import generics

class SnippetList(mixins.ListModelMixin,
                   mixins.CreateModelMixin,
                   generics.MultipleObjectAPIView):
     model = Snippet
     serializer_class = SnippetSerializer
 
     def get(self, request, *args, **kwargs):
         return self.list(request, *args, **kwargs)
 
     def post(self, request, *args, **kwargs):
         return self.create(request, *args, **kwargs)

MultipleObjectAPIView构建了view, 然后加上了inListModelMixin和CreateModelMixin.

基类提供了核心功能,mixin类提供了 .list() 和 .create() 动作。然后显式的把 get 和 post 方法与合适的动作绑定在一起。

##参考资料