`
yzjklove
  • 浏览: 64011 次
  • 性别: Icon_minigender_1
  • 来自: 广东省惠州市
社区版块
存档分类
最新评论

Mix-in技术介绍

阅读更多
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的基类
版权所有 limodou(chatme@263.net) ,如要转载请保留此信息。
分享到:
评论

相关推荐

    Optimization in Product Mix Problem Using Fuzzy Linear Programming

    在实际生产过程中,由于市场、原材料供应等因素的不确定性,导致技术系数和技术参数等存在一定程度的模糊性。这使得传统的线性规划方法难以准确地解决问题,因此引入模糊线性规划成为了必要的手段之一。 #### 模糊...

    论文研究-Cost-Efficient VM Configuration Algorithm in the Cloud using Mix Scaling Approach.pdf

    文章首先介绍了云计算技术的普及和其带来的按需付费模式,这一模式允许用户根据实际使用量支付费用,从而像使用水和电力一样灵活地使用云计算资源。 云计算的一个重要特点是弹性可扩展性。与传统的IT基础架构管理...

    diversity-in-tech:已弃用·Phoenix应用程序根据其友好程度对技术公司进行评分

    使用docker-compose run diversity_in_tech mix deps.get安装安装依赖关系 使用docker-compose run diversity_in_tech mix ecto.create创建数据库 使用docker-compose run diversity_in_tech mix ecto.migrate迁移...

    算法技术手册(Algorithms in Nutshell)英文版

    - 提供进一步学习的资源,帮助读者深入了解算法的相关理论和技术。 #### 二、算法的数学基础(Chapter 2:The Mathematics of Algorithms) - **问题规模**(Section 2.1 Size of a Problem Instance): - 定义...

    将云技术引进企业协作《Collaboration in the Cloud》

    On the technology side, a volatile mix of acronyms like SOA Service Oriented Architecture, SaaS Software as a Service and Web2.0 is brewing that is drastically changing our view on the role and value...

    ATL与WTL学习资料[pdf]

    - **Mix-in类**使得开发者可以轻松地为窗口添加额外行为,例如自定义绘图逻辑。 #### 三、ATL风格的模板 - **模板简介**: - ATL广泛使用C++模板来实现其核心功能。 - 初次接触ATL的开发者可能会觉得模板语法...

    blender-mixamo插件

    使用Blender Mixamo插件时,还需要注意一些技术要点。例如,确保Blender和Mixamo的版本兼容,因为不兼容的版本可能导致某些功能无法正常使用。同时,理解Blender的基础骨骼系统和权重绘画也是必要的,这将有助于你在...

    WTL学习指南(从MFC到WTL的转折)

    3. 高级消息映射和Mix-in类:WTL允许通过Mix-in类实现高级的消息映射,这样可以更方便地扩展窗口类的功能。 4. ATL EXE的结构:理解ATL应用程序的基本结构,包括主消息循环和初始化过程,这对于构建WTL应用程序至关...

    RACE机械软件介绍

    通过In-Fusion HD Enzyme Mix将纯化的RACE产物克隆到适当的载体中,以便进一步的分析和研究。 #### C. RACE产物测序 使用测序仪对克隆后的RACE产物进行测序,以确认序列的准确性并获取完整的5’和3’端序列信息。 ...

    基于INNOVUS平台的云端训练AI芯片设计.pdf

    2. 混合摆放技术(Mix-Place):这是一种创新的设计方法,可以在布局布线阶段评估和修正功耗和压降,以满足PPA(功耗、性能、面积)要求。 3. 快速布局规划(Floorplan):该技术有助于快速完成设计模块的初步规划...

    mix_and_match

    使用的技术 React0.14-rc1 React运动 巴别塔 Webpack 浏览器支持 混合搭配在以下方面进行了测试: IE 9/10/11 Firefox 40/41 Chrome45 的Safari 8 歌剧31/32 如何安装 git clone git@github....

    EmberCliProject

    #Embercliapp 该项目用于与 Ember-CLI 相似。...为ApplicationController定义的Mix-in对所有嵌套的控制器都是继承的3.Ember.Controller、Ember.ArrayController、Ember.ObjectController的区别。 对象模板必须由 EmberO

    基于WTL 双缓冲(double buffer)绘图的分析详解

    在Windows Template Library (WTL) 中,可以使用`CDoubleBufferImpl`和`CDoubleBufferWindowImpl`这两个Mix-in类来实现双缓冲绘图。`CDoubleBufferImpl`适用于那些继承自`CWindowImpl`的类,而`...

    Right mix of speech and non-speech: Hybridauditory feedback in mobility assistance of the visually impaired

    本文所介绍的“Hybridauditory feedback”(混合听觉反馈)是一种创新的技术方法,其核心在于将常用的语音指导信息转换为非语音形式,即“spearcons”(语音图标),这是基于用户行进频率和声音重复性的考虑。...

    CSS3实现水波浪浮动特效.zip

    animation: waterRipple 2s ease-in-out infinite; z-index: -1; } ``` 这里的`::before`伪元素用于创建一个覆盖整个`.water`元素的半透明圆环渐变背景,模拟波浪的外观。`radial-gradient`函数创建了从透明到...

Global site tag (gtag.js) - Google Analytics