使用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的线程来解决生产者消费问题的示例
Apr 02 Python
在Python中操作列表之List.pop()方法的使用
May 21 Python
尝试用最短的Python代码来实现服务器和代理服务器
Jun 23 Python
python bmp转换为jpg 并删除原图的方法
Oct 25 Python
Python绘制并保存指定大小图像的方法
Jan 10 Python
Python实现个人微信号自动监控告警的示例
Jul 03 Python
Django实现web端tailf日志文件功能及实例详解
Jul 28 Python
python 多进程并行编程 ProcessPoolExecutor的实现
Oct 11 Python
python3中pip3安装出错,找不到SSL的解决方式
Dec 12 Python
Python实现剪刀石头布小游戏(与电脑对战)
Dec 31 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
Apr 20 Python
python和js交互调用的方法
Jun 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
php的curl实现get和post的代码
2008/08/23 PHP
php中require和require_once的区别说明
2014/02/27 PHP
jquery全选checkBox功能实现代码(取消全选功能)
2013/12/10 Javascript
利用jquery写的左右轮播图特效
2014/02/12 Javascript
js下将阿拉伯数字每三位一逗号分隔(如:15000000转化为15,000,000)
2014/06/02 Javascript
js style动态设置table高度
2014/10/21 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
javascript每日必学之运算符
2016/02/16 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
JS实现点击按钮可实现编辑功能
2018/07/03 Javascript
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
2019/10/08 Javascript
JS实现电脑虚拟键盘打字测试
2020/06/24 Javascript
跟老齐学Python之玩转字符串(1)
2014/09/14 Python
python 线程的暂停, 恢复, 退出详解及实例
2016/12/06 Python
Python常用算法学习基础教程
2017/04/13 Python
python3 selenium 切换窗口的几种方法小结
2018/05/21 Python
python django 原生sql 获取数据的例子
2019/08/14 Python
python读取word 中指定位置的表格及表格数据
2019/10/23 Python
pymysql模块的操作实例
2019/12/17 Python
简单了解Java Netty Reactor三种线程模型
2020/04/26 Python
Python制作一个仿QQ办公版的图形登录界面
2020/09/22 Python
将不规则的Python多维数组拉平到一维的方法实现
2021/01/11 Python
canvas实现按住鼠标移动绘制出轨迹的示例代码
2018/02/05 HTML / CSS
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
网络工程专业毕业生推荐信
2013/10/28 职场文书
日语求职信范文
2013/12/17 职场文书
2014国培学习感言
2014/03/05 职场文书
党员剖析材料范文
2014/12/18 职场文书
党支部先进事迹材料
2014/12/24 职场文书
酒店工程部岗位职责
2015/02/12 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
原来实习报告是这样写的呀!
2019/07/03 职场文书
简短的人生哲理(38句)
2019/08/13 职场文书
Python一行代码实现自动发邮件功能
2021/05/30 Python
Nginx使用Lua模块实现WAF的原理解析
2021/09/04 Servers