Mixin 的概念

Mixin 即 Mix-in,常被译为“混入”,是一种编程模式,在 Python 等面向对象语言中,通常它是实现了某种功能单元的类,用于被其他子类继承,将功能组合到子类中。

利用 Python 的多重继承,子类可以继承不同功能的 Mixin 类,按需动态组合使用。

当多个类都实现了同一种功能时,这时应该考虑将该功能抽离成 Mixin 类。

举个例子

定义一个简单的类:

class Person:
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age

我们可以通过调用实例属性的方式来访问:

p = Person("小陈", "男", 18)
print(p.name) # "小陈"

然后我们定义一个 Mixin 类:

class MappingMixin:
def __getitem__(self, key):
return self.__dict__.get(key) def __setitem__(self, key, value):
return self.__dict__.set(key, value)

这个类可以让子类拥有像 dict 一样调用属性的功能

我们将这个 Mixin 加入到 Person 类中:

class Person(MappingMixin):
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age

现在 Person 拥有另一种调用属性方式了:

p = Person("小陈", "男", 18)
print(p['name']) # "小陈"
print(p['age']) # 18

再定义一个 Mixin 类,这个类实现了 __repr__ 方法,能自动将属性与值拼接成字符串:

class ReprMixin:
def __repr__(self):
s = self.__class__.__name__ + '('
for k, v in self.__dict__.items():
if not k.startswith('_'):
s += '{}={}, '.format(k, v)
s = s.rstrip(', ') + ')' # 将最后一个逗号和空格换成括号
return s

利用 Python 的特性,一个类可以继承多个父类:

class Person(MappingMixin, ReprMixin):
def __init__(self, name, gender, age):
self.name = name
self.gender = gender
self.age = age

这样这个子类混入了两种功能:

p = Person("小陈", "男", 18)
print(p['name']) # "小陈"
print(p) # Person(name=小陈, gender=男, age=18)

总结

Mixin 实质上是利用语言特性,可以把它看作一种特殊的多重继承,所以它并不是 Python 独享,只要支持多重继承或者类似特性的都可以使用,比如 Ruby 中 include 语法,Vue 等前端领域也有 Mixin 的概念。

但 Mixin 终归不属于语言的语法,为了代码的可读性和可维护性,定义和使用 Mixin 类应该遵循几个原则:

  1. Mixin 实现的功能需要是通用的,并且是单一的,比如上例中两个 Mixin 类都适用于大部分子类,每个 Mixin 只实现一种功能,可按需继承。
  2. Mixin 只用于拓展子类的功能,不能影响子类的主要功能,子类也不能依赖 Mixin。比如上例中 Person 继承不同的 Mixin 只是增加了一些功能,并不影响自身的主要功能。如果是依赖关系,则是真正的基类,不应该用 Mixin 命名。
  3. Mixin 类自身不能进行实例化,仅用于被子类继承。

本文属于原创,首发于微信公众号「面向人生编程」,如需转载请后台留言。

关注后回复以下信息获取更多资源

回复【资料】获取 Python / Java 等学习资源

回复【插件】获取爬虫常用的 Chrome 插件

回复【知乎】获取最新知乎模拟登录

通过 Python 理解 Mixin 概念的更多相关文章

  1. 对于新手来说,Python 中有哪些难以理解的概念?

    老手都是从新手一路过来的,提起Python中难以理解的概念,可能很多人对于Python变量赋值的机制有些疑惑,不过对于习惯于求根究底的程序员,只有深入理解了某个事物本质,掌握了它的客观规律,才能得心应 ...

  2. RxSwift 系列(九) -- 那些难以理解的概念

    前言 看完本系列前面几篇之后,估计大家也还是有点懵逼,本系列前八篇也都是参考RxSwift官方文档和一些概念做的解读.上几篇文章概念性的东西有点多,一时也是很难全部记住,大家脑子里面知道有这么个概念就 ...

  3. 用 Python 理解 Web 并发模型

    用 Python 理解 Web 并发模型 http://www.jianshu.com/users/1b1fde012122/latest_articles   来源:MountainKing 链接: ...

  4. python用法——Mixin

    在读werkzeug和flask的源码中,经常能遇到类名中有mixin这个东西.这个东西的用法让我想到了java中的接口名有able的用法.今天我就来看了看这个mixin是什么东西. 学习了pytho ...

  5. python异常(概念、捕获、传递、抛出)

    异常 目标 异常的概念 捕获异常 异常的传递 抛出异常 01. 异常的概念 程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常 程序停止执 ...

  6. 关于Python的Mixin模式

    转自:http://www.bjhee.com/python-mixin.html 像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病.因为继承应该是个”is-a”关系. ...

  7. 【转载】关于Python的Mixin模式

    本博按: mixin是看起来是多继承的一种,但是,这种继承并不作为父类存在,而是增加功能到子类中. 像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病.因为继承应该是个” ...

  8. Python 字典Dict概念和操作

    # 字典概念:无序的, 可变的键值对集合 # 定义 # 方式1 # {key: value, key: value...} # 例如 # {"name": "xin&qu ...

  9. 以python理解Linux的IO多路复用,select、poll、epoll

    题外话 之前在看Unix环境高级编程的时候,看完高级IO那一章,感觉自己萌萌哒,0.0 ,有点囫囵吞枣的感觉,之后翻了几篇博客,从纯系统的角度理解,稍微有了点概念,以这两篇为例,可以以后参考: htt ...

随机推荐

  1. (JavaScript) base64 字符串 和 ArrayBuffer 之间转换

    base64 --> ArrayBuffer function base64ToUint8Array(base64String) { const padding = '='.repeat((4 ...

  2. 使用 EW 作Socks5代理

    简介: EarthWorm是一款用于开启 SOCKS v5 代理服务的工具,基于标准 C 开发,可提供多平台间的转接通讯,用于复杂网络环境下的数据转发. 主页: http://rootkiter.co ...

  3. SQLserver2016对字段是json对象查询

    现在2016内置对json对象的查询支持了.正好项目中用到,做个备忘 如果字段内容是: [{"tagid":"100015","orderid&quo ...

  4. C函数库errno.h概况

    在linux中使用c语言编程时,errno是个很有用的动动.他可以把最后一次调用c的方法的错误代码保留.但是如果最后一次成功的调用c的方法,errno不会改变.因此,只有在c语言函数返回值异常时,再检 ...

  5. 使用Typescript重构axios(二十四)——防御XSRF攻击

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  6. wangkoala杂题总集(根据个人进度选更)

    CQOI2014 数三角形 首先一看题,先容斥一波,求出网格内选三个点所有的情况,也就是C(n*m,3);然后抛出行里三点共线的方案数:C(n,3)*m; 同理就有列中三点共线的方案数:n*C(m,3 ...

  7. Python脚本之——API自动化框架总结

    学完了Python脚本接口自动化之后,一直没有对该框架做总结,今天终于试着来做一份总结了. 框架结构如下图: 来说一下每个目录的作用: Configs:该目录下存放的是.conf,.ini文件格式的配 ...

  8. LINQ学习——JOIN

    一.JOIN的作用 1.使用联接来结合两个或更多的集合的数据. 2.联接操作接受两个集合然后创建一个临时的对象集合,每一个对象包含原始集合对象中的所有字段. Note:这里是包含而不是这个原实集合的字 ...

  9. docker——端口映射

    端口映射 1.就是把容器的端口映射为宿主机的一个随机或者特定端口 2.使得外部用户可以访问容器服务 3.本质其实就是在底层做了iptables地址转发 4.出去的流量是做SNAT原地址转发 5.进来的 ...

  10. js数组方法大全(上)

    # js数组方法大全(上) 记录一下整理的js数组方法,免得每次要找方法都找不到.图片有点多,注意流量,嘻嘻! 本期分享 join() reverse() sort() concat() slice( ...