`
yezongbo
  • 浏览: 30340 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IntroMixin

阅读更多

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的基类

 

分享到:
评论

相关推荐

    只需要用一张图片素材文档选择器.zip

    只需要用一张图片素材文档选择器.zip

    浙江大学842真题09-24 不含答案 信号与系统和数字电路

    浙江大学842真题09-24 不含答案 信号与系统和数字电路

    无标题baci和jbaci

    无标题baci和jbaci

    完整的雷达系统仿真程序,完整的雷达系统仿真程序 matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    实体商品销售源码最新优化.zip

    实体商品销售源码最新优化.zip

    戴尔存储MD1400机柜维护操作与安全指导

    内容概要:本文档详细介绍了戴尔存储MD1400机柜的安全注意事项、电源指示灯解释、故障排除方法以及硬件维护步骤,包括卸下和安装直流电源设备、硬盘驱动器和背板的具体操作流程。 适用人群:IT运维人员、数据中心管理员和技术支持工程师。 使用场景及目标:在维护和管理戴尔存储MD1400机柜时作为参考指南,确保正确安装和故障排查,避免安全隐患和设备损坏。 其他说明:文档提供了丰富的图文指导,帮助使用者更好地理解和执行相关操作。

    PyClass 课程计划.zip

    PyClass 课程计划Noisebridge Python 课程每周一晚上 7 点至 9 点(太平洋时间)在旧金山 Noisebridge 二楼电子室举行。自 2024 年 8 月起,该课程目前暂停。请参阅 wiki 页面了解更多信息。本课程免费!如果您希望捐款,请捐赠给 Noisebridge。建议捐款15 美元、50 美元、200 美元以上建议每月捐款每月 10 美元、20 美元、40 美元、80 美元以上所有 Python 课程均遵循Noisebridge 反骚扰政策、 Noisebridge 冲突解决指南和 recurse.org 社交规则课后,我们欢迎您提供反馈! 在此提交表格内容课程课程描述新生阅读迭代次数Noisebridge Python 课程至少早在 2015 年就已经存在,拥有许多不同的讲师和版本。从 2017 年到 2018 年,该课程似乎由Jared Garst负责。(?)。从 2023 年到 2024 年,该课程由Travis Briggs负责。如果您有其他关于此类历史的信息想要分享,请在此处创建 PR、

    自动化部署管道创建的代码库(含 Concourse 和 Jenkins 相关).zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。

    一种新的混合优化算法,即瞬态三角哈里斯鹰优化器(Tthho) matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    1-中国各地万达广场地理分布数据2006-2021-社科数据.zip

    万达广场作为城市综合体的代表,在中国各地的地理分布数据集覆盖了2006至2021年。这些数据详细记录了万达广场的多个关键指标,包括项目名称、项目信息、具体地点、开业时间、商业面积以及精确的经度和纬度。万达广场不仅是商业地产开发的先行者,还以其成熟的商业模式、完善的产业链和丰富的商业资源,在全国范围内形成了独立的大型商圈。这些综合体集购物、餐饮、文化、娱乐等多种功能于一体,对提升城市商业档次、增加就业岗位、创造税收以及丰富群众消费需求等方面产生了显著的社会效益。数据集提供了420条样本,为研究中国区域经济发展特征及其未来趋势提供了宝贵的信息资源。

    正在月下弹琴的古装美女flash场景动画.zip

    正在月下弹琴的古装美女flash场景动画.zip

    理光Ricoh-MP C8003打印机驱动下载

    理光 MP C8003 是一款彩色激光多功能数码复合机。 【基础性能】 打印复印速度:黑白和彩色打印 / 复印速度均可达 80 页每分钟,能够快速高效地完成大量文档的输出任务,有效提高工作效率 分辨率:拥有 1200x4800dpi 的高分辨率,可输出色彩鲜艳、细节丰富、图像清晰的文档和图像,满足专业级的打印和复印需求,尤其适合对色彩精度要求较高的设计图纸、宣传资料等文件的输出 首张输出时间:黑白首张复印时间为 4.7 秒,彩色首张复印时间为 6.3 秒,在启动打印或复印任务时无需长时间等待,可迅速响应,进一步提升工作效率 纸张容量:标准配置的纸张容量为单 2500 页抽屉和双 550 页抽屉,还可通过扩展将纸张容量从 3700 页提升至 8100 页,能够满足不同规模的打印任务需求,减少纸张添加的频率 【功能多样性】 多功能一体:集复印、打印、扫描、传真功能于一身,可满足办公室多样化的文档处理需求,一台设备即可替代多台单一功能的设备,节省空间和成本 扫描功能:具备高速扫描能力,可通过多种扫描至选项将原件扫描并以电子形式分发,支持将扫描后的文件直接发送至个人移动设备

    《The Annotated Transformer》环境配置

    《The Annotated Transformer》环境配置

    基于深度学习resnet50和vgg16卷积神经网络的汉字书法识别项目源码+训练集+测试集 【可用于课设-毕设】

    深度学习大作业基于resnet50和vgg16卷积神经网络的汉字书法识别项目源码+训练集+测试集 操作步骤 将下载的训练集和测试集,解压到工程中 运行对应的data.py文件,进行转录,将原始数据集转录为numpy矩阵,生成data.npy及label.npy 运行对应的train.py进行训练 运行test.py使用训练完成的网络测试。

    直接序列扩频(DSSS) matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    代码

    代码

    ECharts柱状图-基础柱状图.rar

    图表效果及代码实现讲解链接:https://blog.csdn.net/zhangjiujiu/article/details/143996614

    Spring Data Key Value 特性的示例项目.zip

    1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。

    营销策划 -魔術絲-黑松露香蕉莓果饮品-新品发布会产品介绍-终版.pptx

    营销策划 -魔術絲-黑松露香蕉莓果饮品-新品发布会产品介绍-终版.pptx

    成都市数据条例.docx

    成都市数据条例.docx

Global site tag (gtag.js) - Google Analytics