Python Mixin技术介绍
1. Mix-in技术介绍
Mixin可以译为混入,就是在不改变原对象的情况下对其进行扩展。本文介绍了在 Python 语言中,如何实现Mixin技术,及安装的相应技巧。
1.1. 什么是Mix-in技术
Mix- in技术,中文不知道应该如何称呼,但意思好象是混入。它的作用是,在运行期间,动态改变类的基类或类的方法,从而使得类的表现可以发生变化。可以用在一 个通用类接口中,根据不同的选择使用不同的低层类实现,而高层类不用发生变化。而且这一实现可以在运行过程中动态进行改变。由于我也是刚看到,大家有问题 可以与我进行交流。这就是我看到的文章的链接。
1.2. 基类的增加
有一个类,
class foo:
pass
我可以定义另外一个类,
class foobase:
def hello(self):
print "hello"
如果我直接调用:
>>> obj=foo()
>>> obj.hello()
这时你会看到出错。那么我可以这样:
>>> foo.__bases__ +=(foobase,)
>>> obj.hello()
hello
成功了。原理是,每个类都有一个bases属性,它是一个tuple,用来存放所有的基类。而且在运行中,可以动态改变。所以当我们向其中增加新的基类时,再次调用原来不存在的函数,由于基类中的函数已经存在了,所以这次成功了。
这是一个最简单的应用,可以看到我们可以动态改变类的基类。有几个注意事项要说一下:
__bases__是一个tuple,所以增加一个值要使用tuple类型,而单个元素tuple的写法为(foobase,)
类必须先存在。所以,如果想使用这一技术,先要将相关的类的模块导入(import)。
由于Mix-in是一种动态技术,以多继承,对象为基础,而python正好是这样的语言,使得在python中实现这一技术非常容易。
1.3. 函数替换
在前面,简单地向大家介绍了一下Mix-in技术,它实现了基类的动态增加。这样我们就可以在运行时,根据选择可以动态地增加基类,从而实现不同的目的。现在还有一个问题,就是,在基类与派生类中都有同名的函数,要如何处理呢?
在Python中,如果派生类中有与基类同名的函数,那么调用函数时,会调用派生类的函数,而不是基类的函数,可以测试一下:
>>> class foobase:
def a(self):
print "hello"
>>> class foo(foobase):
def a(self):
print "foo"
>>> c=foo()
>>> c.a()
foo
可以看出,执行的是foo类的函数。这样在使用Mix-in技术时,如果原来的类中存在与Mix类中同名的函数,那么Mix类中的函数不会运行,如果想对其进行替换怎么办呢?方法就是使用getattr()和setattr()函数。当然还是最简单的。
定义两个类:
>>> class foobase:
def a(self):
print "hello"
>>> class foo:
def a(self):
print "foo"
>>> f=getattr(foobase, "a")
>>> setattr(foo, "a", f.im_func) #f.im_func会得到真正的函数对象
>>> c=foo()
>>> c.a()
hello
可以看到,函数被替换了。
注意,使用dir(f)还会看到其它的属性im_class,它表示这个函数属于哪个类,im_self表示属于哪个实例。
1.4. Mix-in安装函数
前面讲了基本的实现技术,下面给大家介绍一个Mix-in安装函数,这个函数是从前面所说的文章copy下来的。
import types
def MixIn(pyClass, mixInClass, makeAncestor=0):
if makeAncestor:
if mixInClass not in pyClass.__bases__:
pyClass.__bases__ = (mixInClass,) + pyClass.__bases__
else:
# Recursively traverse the mix-in ancestor
# classes in order to support inheritance
baseClasses = list(mixInClass.__bases__)
baseClasses.reverse()
for baseClass in baseClasses:
MixIn(pyClass, baseClass)
# Install the mix-in methods into the class
for name in dir(mixInClass):
if not name.startswith('__'):
# skip private members
member = getattr(mixInClass, name)
if type(member) is types.MethodType:
member = member.im_func
setattr(pyClass, name, member)
这 个函数可以将某个mix-in类安装为指定类的基类,同时可以通过关键字参数指定在基类中的顺序,是最前还是最后。因为Python在处理基类时,是安顺 序进行的,所以安装在最前则优先级最高。同时对于指定类的方法如果在mix-in类中存在,则将指定类中的方法替换成mix-in类中的方法。
if makeAncestor:
if mixInClass not in pyClass.__bases__:
pyClass.__bases__ = (mixInClass,) + pyClass.__bases__
如果makeAncestor为1,表示是安装在最前,则首先判断在pyClass的基类中是否存在mixInClass类,如果不存在,再进行安装。
else:
# Recursively traverse the mix-in ancestor
# classes in order to support inheritance
baseClasses = list(mixInClass.__bases__)
baseClasses.reverse()
for baseClass in baseClasses:
MixIn(pyClass, baseClass)
如 果makeAncestor为0,并不将mixInClass安装在最后,原作者说他在实际中没有这样用的。那么它完成什么任务呢?它实际完成了一个递 归,即从mixInClass的最底层的基类开始(因为mixInClass也可能是多重继承而来的),对pyClass中也存在的函数进行替换。这样执 行完毕后,mixInClass类中,包含所有基类中的函数,如果有与pyClass类中的函数重名的,都将pyClass中的函数替换成 mixInClass相应的函数。(有些复杂!)
# Install the mix-in methods into the class
for name in dir(mixInClass):
if not name.startswith('__'):
# skip private members
member = getattr(mixInClass, name)
if type(member) is types.MethodType:
member = member.im_func
setattr(pyClass, name, member)
这 步完成重名函数的替换。首先去掉私有方法(私有方法名前有'__').得到mixInClass类中的指定名字的方法对象,判断是否为方法类型。因为还有 可能取到属性。在types模块中包含了一些类型,可以用它来判断是否为方法类型。对于方法对象,如果是类方法,实际的函数应使用它的属性 im_func。然后将pyClass相应的方法替换成mixInClass中的方法。
这样就将mixInClass安装为pyClass的基类了。
使用例子如:
from classa import classa
from classb import classb
MixIn(classa, classb) #将classb安装为classa的基类
转载于:https://www.cnblogs.com/huazi/archive/2012/05/09/2492041.html
Python Mixin技术介绍相关推荐
- python软件界面-python软件界面介绍(python软件介绍)
python软件界面介绍 1.接口初始化 当我们使用pycharm工具时,我们将遇到的第一个问题是,在进行各种配置后界面变得混乱时,我们该怎么办?我们应该还原,那么如何还原初始设置? 尽管此工具是从e ...
- python url模块介绍_python 中 urlparse 模块介绍
urlparse模块主要是用于解析url中的参数 对url按照一定格式进行 拆分或拼接 1.urlparse.urlparse 将url分为6个部分,返回一个包含6个字符串项目的元组:协议.位置.路 ...
- 7套干货,Python常用技术学习知识图谱!!(史上最全,建议收藏)
大家好,我是明月十四桥! 你要偷偷努力,然后惊艳所有人~ 给大家推荐 7 个宝藏级教程,视频课是永久有效的,可以随时学习,有几门课程还有CSDN官方学习答疑群,课程右边扫码入群,讲师在群里答疑哈~ 目 ...
- Python开发技术详解PDF
Python开发技术详解(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1F5J9mFfHKgwhkC5KuPd0Pw 提取码:xxy3 复制这段内容后打开百度网盘手 ...
- 《Getting Started with WebRTC》第二章 WebRTC技术介绍
<Getting Started with WebRTC>第二章 WebRTC技术介绍 本章作WebRTC的技术介绍,主要讲下面的概念: . 怎样建立P2P的通信 . 有效的信 ...
- Python实战技术 - Python虚拟隔离环境 和 Docker技术
Python实战技术 - Python虚拟隔离环境 和 Docker技术 已经学过,只想查查手册?--试试直接跳转到命令: (1)使用venv创建相关命令 (2)使用virtualenv创建相关命令 ...
- 容器技术介绍之docker核心技术概述
容器简单来说是一种沙盒技术,将应用"装"进沙盒中,像集装箱一样,把应用封装起来,使得应用之间不会相互干扰,而放进沙盒中的应用也方便"搬家".本文基于docker ...
- Frida-Dexdump 脱壳工具下载使用以及相关技术介绍
Frida-Dexdump 脱壳工具下载使用以及相关技术介绍 文章目录 Frida-Dexdump 脱壳工具下载使用以及相关技术介绍 前言 一.查壳.反编译.APK工具推荐 二.查壳 1.方式1 2. ...
- Python+爬虫技术获取斗鱼直播图片(整理)
核心内容: 1.爬虫的基本原理 2.利用Python爬取数据的方法(使用urllib爬取数据) 3.从斗鱼直播平台爬取图片 最近因为工作的原因,要利用爬虫的相关技术,获取html网页相关的数据,特意总 ...
最新文章
- iOS中你可能没有完全弄清楚的(一)synthesize
- Verilog中的二维数组及其初始化
- Windows 2000和WindowsXP中神秘的数字签名
- Uva12716 素数筛思想的应用
- 【MFC】带组合框的工具栏
- 从用户观点对计算机如何分类,从用户的观点看操作系统是
- me)不支持html,属于me的vue练习(参考菜鸟教程).html
- pcm 8k单声道和双声道采样_音频接口PCM
- 第7章-选择器+伪类
- 【关键词提取】第二篇:数据集、实现代码介绍
- linux 添加新用户时常用的操作
- [Share]前端开发大众手册(包括工具、网址、经验等)
- 少走弯路,给3~5年java程序员的唯一一条建议
- 步进电机和伺服电机的区别
- 基于国密算法SM2非证书标识公钥密码技术(IPK)
- 众泰Z700导航升级高德地图
- DAY1(02-HTML标签(上))
- 亚信卸载-无需密码卸载
- Java程序员必看的15本书的电子版下载地址
- LANDesk准入认证客户端 每次启动都丢失