為什么需要Mix-in?
在學習面向對象時我們知道,類可以通過繼承類獲得屬性和方法,通過繼承可以減少重復代碼、提高復用率。Python支持多繼承,一個類可以通過繼承多個類來得到它們的功能。但多繼承會帶來一些問題,比如屬性沖突。那么有沒有可能只繼承類的方法呢?
當然方法名稱也可能沖突。但如果合理地劃分功能的話,這種可能性很小。
Mix-in類(混入類):只定義一些方法給子類使用,不定義自己的實例屬性,也不要求調用它的__init__
方法。Mix-in類并不是新的語法,只是一種特殊的類,只用來提供方法。
在實際的代碼中,我們經常會看到Mixin結尾的類(如
SingleObjectMixin
),這是一種命名約定,名稱其實不會影響功能。
Mix-in 實例
這里借用 通過 Python 理解 Mixin 概念舉的例子。
class MappingMixin:def __getitem__(self, key):return self.__dict__.get(key)def __setitem__(self, key, value):return self.__dict__.set(key, value)class Person(MappingMixin):def __init__(self, name, gender, age):self.name = nameself.gender = genderself.age = agep = Person("小陳", "男", 18)
print(p['name']) # "小陳"
print(p['age']) # 18
首先定義了一個Person
類,然后我們能用字典訪問Person
,于是定義了一個只有方法的MappingMixin
類,并讓Person
繼承MappingMixin
的方法。
另一個例子 python 中Mixin混入類的用法:
class Tel:def telfunc(self):print("我可以接打電話")
?
?
class SMS:def smsfunc(self):print("我可以發短信")
?
?
class Phone(Tel, SMS):def __init__(self, sn):self.sn = sn
?def welcome(self):print("welcome {}".format(self.sn))
?
?
p = Phone("xiaomi")
p.telfunc()
p.smsfunc()
p.welcome()
Django中的Mix-in
Django中有很多Mixin類。在django.views.generic.base
中存在如下關系:
View
是一個基類(可以說是一個抽象基類),實現了核心功能如dispatch
。dispatch
委托具體子類的處理方法。
TemplateResponseMixin
為使用模板的視圖提供了功能。
RedirectView
類只繼承 View
,可以看到,它實現了 get
、head
、post
等方法。
TemplateView
只用于顯示內容,因此它只實現了 get
方法。由于它需要相關的模板功能,所以繼承了TemplateResponseMixin
。
Django中很多實現都依賴了Mix-in類,而我們在使用Django開發的時候,也可以利用(內置的和自定義的)Mix-in類提供功能。
django mixin文檔
參考鏈接
- 通過 Python 理解 Mixin 概念
- python 中Mixin混入類的用法
- 《流暢的Python》第12章:繼承的優缺點
- 《Effective Python》(第二版)41.考慮使用Mix-in Classes組合功能
- django mixin文檔