使用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基于select实现的socket服务器
Apr 13 Python
python使用matplotlib绘制折线图教程
Feb 08 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
Dec 14 Python
python 获取utc时间转化为本地时间的方法
Dec 31 Python
django使用admin站点上传图片的实例
Jul 28 Python
命令行运行Python脚本时传入参数的三种方式详解
Oct 11 Python
Pytorch maxpool的ceil_mode用法
Feb 18 Python
python构造IP报文实例
May 05 Python
如何搭建pytorch环境的方法步骤
May 06 Python
Django自关联实现多级联动查询实例
May 19 Python
记一次django内存异常排查及解决方法
Aug 07 Python
Python实现批量自动整理文件
Mar 16 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
百事可乐也出咖啡了 双倍咖啡因双倍快乐
2021/03/03 咖啡文化
PHP实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
PHP连接MSSQL2008/2005数据库(SQLSRV)配置实例
2014/10/22 PHP
PHP 7的一些引人注目的新特性简单介绍
2015/11/08 PHP
PHP的Yii框架入门使用教程
2016/02/15 PHP
PHP使用curl模拟post上传及接收文件的方法
2016/03/04 PHP
javascript获取鼠标位置部分的实例代码(兼容IE,FF)
2013/08/05 Javascript
JQuery的ON()方法支持的所有事件罗列
2015/02/28 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
javascript框架设计之类工厂
2015/06/23 Javascript
基于JS实现数字+字母+中文的混合排序方法
2016/06/06 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
ES6中Symbol类型用法实例详解
2017/04/06 Javascript
详解微信第三方小程序代开发
2017/06/23 Javascript
详解vue使用vue-layer-mobile组件实现toast,loading效果
2018/08/31 Javascript
Javascript读写cookie的实例源码
2019/03/16 Javascript
微信小程序地图导航功能实现完整源代码附效果图(推荐)
2019/04/28 Javascript
了解重排与重绘
2019/05/29 Javascript
vue实现多组关键词对应高亮显示功能
2019/07/25 Javascript
Javascript执行流程细节原理解析
2020/05/14 Javascript
JavaScript鼠标悬停事件用法解析
2020/05/15 Javascript
jQuery实现鼠标拖拽登录框移动效果
2020/09/13 jQuery
你眼中的Python大牛 应该都有这份书单
2017/10/31 Python
Python pymongo模块常用操作分析
2018/09/01 Python
Python Pandas分组聚合的实现方法
2019/07/02 Python
Python队列RabbitMQ 使用方法实例记录
2019/08/05 Python
基于PyTorch中view的用法说明
2021/03/03 Python
美国网上眼镜商城:Zenni Optical
2016/11/20 全球购物
彪马西班牙官网:PUMA西班牙
2019/06/18 全球购物
医学类个人求职信范文
2014/02/05 职场文书
2014年护士长工作总结
2014/11/11 职场文书
2014年体检中心工作总结
2014/12/23 职场文书
毕业生自荐信范文
2015/03/05 职场文书
签字仪式主持词
2015/07/03 职场文书
MySQL实例精讲单行函数以及字符数学日期流程控制
2021/10/15 MySQL
JavaScript函数柯里化
2021/11/07 Javascript