通过 Python 理解 Mixin 概念
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 类应该遵循几个原则:
- Mixin 实现的功能需要是通用的,并且是单一的,比如上例中两个 Mixin 类都适用于大部分子类,每个 Mixin 只实现一种功能,可按需继承。
- Mixin 只用于拓展子类的功能,不能影响子类的主要功能,子类也不能依赖 Mixin。比如上例中
Person继承不同的 Mixin 只是增加了一些功能,并不影响自身的主要功能。如果是依赖关系,则是真正的基类,不应该用 Mixin 命名。 - Mixin 类自身不能进行实例化,仅用于被子类继承。
本文属于原创,首发于微信公众号「面向人生编程」,如需转载请后台留言。

关注后回复以下信息获取更多资源
回复【资料】获取 Python / Java 等学习资源
回复【插件】获取爬虫常用的 Chrome 插件
回复【知乎】获取最新知乎模拟登录
通过 Python 理解 Mixin 概念的更多相关文章
- 对于新手来说,Python 中有哪些难以理解的概念?
老手都是从新手一路过来的,提起Python中难以理解的概念,可能很多人对于Python变量赋值的机制有些疑惑,不过对于习惯于求根究底的程序员,只有深入理解了某个事物本质,掌握了它的客观规律,才能得心应 ...
- RxSwift 系列(九) -- 那些难以理解的概念
前言 看完本系列前面几篇之后,估计大家也还是有点懵逼,本系列前八篇也都是参考RxSwift官方文档和一些概念做的解读.上几篇文章概念性的东西有点多,一时也是很难全部记住,大家脑子里面知道有这么个概念就 ...
- 用 Python 理解 Web 并发模型
用 Python 理解 Web 并发模型 http://www.jianshu.com/users/1b1fde012122/latest_articles 来源:MountainKing 链接: ...
- python用法——Mixin
在读werkzeug和flask的源码中,经常能遇到类名中有mixin这个东西.这个东西的用法让我想到了java中的接口名有able的用法.今天我就来看了看这个mixin是什么东西. 学习了pytho ...
- python异常(概念、捕获、传递、抛出)
异常 目标 异常的概念 捕获异常 异常的传递 抛出异常 01. 异常的概念 程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常 程序停止执 ...
- 关于Python的Mixin模式
转自:http://www.bjhee.com/python-mixin.html 像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病.因为继承应该是个”is-a”关系. ...
- 【转载】关于Python的Mixin模式
本博按: mixin是看起来是多继承的一种,但是,这种继承并不作为父类存在,而是增加功能到子类中. 像C或C++这类语言都支持多重继承,一个子类可以有多个父类,这样的设计常被人诟病.因为继承应该是个” ...
- Python 字典Dict概念和操作
# 字典概念:无序的, 可变的键值对集合 # 定义 # 方式1 # {key: value, key: value...} # 例如 # {"name": "xin&qu ...
- 以python理解Linux的IO多路复用,select、poll、epoll
题外话 之前在看Unix环境高级编程的时候,看完高级IO那一章,感觉自己萌萌哒,0.0 ,有点囫囵吞枣的感觉,之后翻了几篇博客,从纯系统的角度理解,稍微有了点概念,以这两篇为例,可以以后参考: htt ...
随机推荐
- GCC中,可以使用未声明过的函数
今天代码中使用了一个函数,这个函数也是自定义的,但是还没来得及声明和定义,可以编译时竟然未报错,网上查了下果然,GCC中可以使用未声明的函数http://bbs.csdn.net/topics/390 ...
- foreach数组并直接改变数组内容
<?php $arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is ...
- Tomcat因项目迁移,启动窗口一闪而过,启动失败的解决办法。
笔者手动部署一个web项目到Tomcat/webapps/目录下,成功运行.后来,项目结束,我把webapps下的姓项目文件夹删除.重启Tomcat时,运行...\apache-tomcat-8.5. ...
- podman初试-和docker对比
podman初试-和docker对比 1,什么是docker? Docker 是一个开源的应用容器引擎,属于 Linux 容器的一种封装,Docker 提供简单易用的容器使用接口,让开发者可以打包他们 ...
- php从数据库获取数据并遍历在表格中
<?php /*连接数据库并以一个数组的形式获得数据*/ header("Content-type:text/html;charset=UTF-8"); $con = mys ...
- P3106 [USACO14OPEN]GPS的决斗(最短路)
化简:够简的了.....但是!翻译绝对有锅. 这个最短路是从n到每个点的单源最短路,也就是最短路径树. 那么,思路就很明确了.建两个图,然后跑两边SPFA,记录下最短路径. 然后,对于两点之间的边,如 ...
- centos7 yum 安装 mysql5.7
1.查看系统中是否已安装 MySQL 服务,以下提供两种方式: rpm -qa | grep mysqlyum list installed | grep mysql 2.如果已安装则删除 MySQL ...
- Project Euler 53: Combinatoric selections
从12345这个数字中挑选出三个数共有十种方式: \[ 123, 124, 125, 134, 135, 145, 234, 235, 245,345 \] 在组合学中,我们将其记为\(C(5,3)= ...
- 开发板,pc,虚拟机三者如何互相ping通
1 安装虚拟机时,主机和虚拟机必须是桥接网卡,保证了ip 同一:192,168,1,xx 2 打开虚拟机之前,先把pc机的无线网卡禁用掉只能使用本地连接,pc通过网线连接上网,打开虚拟机,命令行输入: ...
- java多线程与线程并发五:多个线程访问共享对象和数据的方式
本节的内容主要是对前面几节提到的线程间共享数据的方式做一个总结. 线程之间共享数据有以下几种方式: 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象. 2.如果每个线程执行的代码不同 ...