使用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中使用HTMLParser解析html实例
Feb 08 Python
Python基于select实现的socket服务器
Apr 13 Python
PyQt5每天必学之布局管理
Apr 19 Python
python爬取cnvd漏洞库信息的实例
Feb 14 Python
Python进阶之@property动态属性的实现
Apr 01 Python
如何不用安装python就能在.NET里调用Python库
Jul 12 Python
对python 树状嵌套结构的实现思路详解
Aug 09 Python
python argparser的具体使用
Nov 10 Python
python3 动态模块导入与全局变量使用实例
Dec 22 Python
python argparse模块通过后台传递参数实例
Apr 20 Python
Windows下Anaconda和PyCharm的安装与使用详解
Apr 23 Python
Python第三方包PrettyTable安装及用法解析
Jul 08 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中实现图片的锐化
2006/10/09 PHP
php中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
PHP基于CURL进行POST数据上传实例
2014/11/10 PHP
php数组查找函数总结
2014/11/18 PHP
PHP实现导出带样式的Excel
2016/08/28 PHP
php7连接MySQL实现简易查询程序的方法
2020/10/13 PHP
超强的IE背景图片闪烁(抖动)的解决办法
2007/09/09 Javascript
写出高效jquery代码的19条指南
2014/03/19 Javascript
基于JavaScript实现智能右键菜单
2016/03/02 Javascript
微信小程序开发之录音机 音频播放 动画实例 (真机可用)
2016/12/08 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
js实现随机数字字母验证码
2017/06/19 Javascript
javascript实现QQ空间相册展示源码
2017/12/12 Javascript
vue 设置proxyTable参数进行代理跨域
2018/04/09 Javascript
Angular 中使用 FineReport不显示报表直接打印预览
2019/08/21 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
2020/10/20 Javascript
Vue与React的区别和优势对比
2020/12/18 Vue.js
初步讲解Python中的元组概念
2015/05/21 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
纯python实现机器学习之kNN算法示例
2018/03/01 Python
python的pip安装以及使用教程
2018/09/18 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
python连接mongodb密码认证实例
2018/10/16 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
python_mask_array的用法
2020/02/18 Python
Python super()方法原理详解
2020/03/31 Python
css3之UI元素状态伪类选择器实例演示
2017/08/11 HTML / CSS
CSS3与动画有关的属性transition、animation、transform对比(史上最全版)
2017/08/18 HTML / CSS
全天然狗零食:Best Bully Sticks
2016/09/22 全球购物
翻新二手苹果产品的网络领导者:Mac of all Trades
2017/12/19 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?
2013/02/17 面试题
婚庆司仪主持词
2014/03/15 职场文书
2014乡镇党政班子四风问题思想汇报
2014/09/14 职场文书
JS中一些高效的魔法运算符总结
2021/05/06 Javascript
Spring-cloud Config Server的3种配置方式
2021/09/25 Java/Android
基于angular实现树形二级表格
2021/10/16 Javascript