使用Mixin设计模式进行Python编程的方法讲解


Posted in Python onJune 21, 2016

Mixin模式是一种在python里经常使用的模式,适当合理的应用能够达到复用代码,合理组织代码结构的目的。

Python的Mixin模式可以通过多继承的方式来实现, 举例来说,我们自定义一个简单的具有嵌套结构的数据容器:

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通过python内置类型Dict来存放数据,不过到目前为止想要访问对应的数据还是得直接调用里面的字典,没法像原生的字典一样方便的通过暴露出来的api访问数据。当然也可以从头开始把完整的Dictionary Interface完全实现个遍,不过在每个自定义的类似的容器中都来一套肯定不行,这时候利用python内置的UserDict.DictMixin就是一个不错的方式:

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()

通过实现最小的Dictionary Interface,还有继承DictMixin实现Mixin模式,我们就轻松获得了完整的原生字典的行为:下表语法,get, has_keys, iteritems, itervalues甚至还有iterable protocol implementation等一系列的方法和实现。

很多框架比如Django, Django rest framework里面就普遍用到了Mixin这种模式,定义api或者viewset的时候就能够通过多重继承的方式服用一些功能

当然,Mixin模式也不能滥用,至少他会污染你新定义的类,有时候还会带来MRO的问题;不过把一些基础和单一的功能比如一般希望通过interface/protocol实现的功能放进Mixin模块里面还是不错的选择:

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

其实整个理解下来无非就是通过组合的方式获得更多的功能,有点像C#, java里面的interface,强调“it can”的意思,但相比起来简单多了,不需要显示的约束,而且mixin模块自带实现。在使用的时候一般把mixin的类放在父类的右边似乎也是为了强调这并不是典型的多继承,是一种特殊的多继承,而是在继承了一个基类的基础上,顺带利用多重继承的功能给这个子类添点料,增加一些其他的功能。保证Mixin的类功能单一具体,混入之后,新的类的MRO树其实也会相对很简单,并不会引起混乱。

Python 相关文章推荐
Python实现Tab自动补全和历史命令管理的方法
Mar 12 Python
Python语言的变量认识及操作方法
Feb 11 Python
python判断输入日期为第几天的实例
Nov 13 Python
Linux下远程连接Jupyter+pyspark部署教程
Jun 21 Python
python批量读取文件名并写入txt文件中
Sep 05 Python
Python+OpenCV实现实时眼动追踪的示例代码
Nov 11 Python
keras获得model中某一层的某一个Tensor的输出维度教程
Jan 24 Python
如何在mac版pycharm选择python版本
Jul 21 Python
Python 如何实现访问者模式
Jul 28 Python
使用Python爬取Json数据的示例代码
Dec 07 Python
Python爬虫分析微博热搜关键词的实现代码
Feb 22 Python
聊聊pytorch测试的时候为何要加上model.eval()
May 23 Python
详解Python中的from..import绝对导入语句
Jun 21 #Python
Java多线程编程中ThreadLocal类的用法及深入
Jun 21 #Python
深入解析Python中的__builtins__内建对象
Jun 21 #Python
浅谈Python中函数的参数传递
Jun 21 #Python
对比Python中__getattr__和 __getattribute__获取属性的用法
Jun 21 #Python
常见python正则用法的简单实例
Jun 21 #Python
小议Python中自定义函数的可变参数的使用及注意点
Jun 21 #Python
You might like
在Windows中安装Apache2和PHP4的权威指南
2006/10/09 PHP
thinkphp浏览历史功能实现方法
2014/10/29 PHP
php截取中文字符串函数实例
2015/02/23 PHP
php中实现进程锁与多进程的方法
2016/09/18 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
在Laravel 的 Blade 模版中实现定义变量
2019/10/14 PHP
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
javascript options属性集合操作代码
2009/12/28 Javascript
基于Jquery的文字自动截取(提供源代码)
2011/08/09 Javascript
写出高效jquery代码的19条指南
2014/03/19 Javascript
jQuery中even选择器的定义和用法
2014/12/23 Javascript
学习JavaScript编程语言的8张思维导图分享
2015/03/27 Javascript
vue.js树形组件之删除双击增加分支实例代码
2017/02/28 Javascript
angularjs封装$http为factory的方法
2017/05/18 Javascript
jQuery回调方法使用示例
2017/06/26 jQuery
Vue.js框架路由使用方法实例详解
2017/08/25 Javascript
javascript、php关键字搜索函数的使用方法
2018/05/29 Javascript
一些手写JavaScript常用的函数汇总
2019/04/16 Javascript
websocket4.0+typescript 实现热更新的方法
2019/08/14 Javascript
Python字符遍历的艺术
2008/09/06 Python
Python实现国外赌场热门游戏Craps(双骰子)
2015/03/31 Python
python使用正则表达式提取网页URL的方法
2015/05/26 Python
python实现linux下使用xcopy的方法
2015/06/28 Python
python根据url地址下载小文件的实例
2018/12/18 Python
python实现字符串加密成纯数字
2019/03/19 Python
一步步教你用python的scrapy编写一个爬虫
2019/04/17 Python
Flask框架搭建虚拟环境的步骤分析
2019/12/21 Python
Python爬虫爬取微信朋友圈
2020/08/06 Python
美国在线医疗分销商:MedEx Supply
2020/02/04 全球购物
如何转换一个字符串到enum值
2014/04/12 面试题
课前三分钟演讲稿
2014/04/24 职场文书
2015年教师党员承诺书
2015/04/27 职场文书
幼儿园小班班务总结
2015/08/03 职场文书
个人业务学习心得体会
2016/01/25 职场文书
日本动漫十大公认神作:第五现已全网禁播,《死亡笔记》在榜
2022/03/18 日漫
基于Python实现流星雨效果的绘制
2022/03/18 Python