zoukankan      html  css  js  c++  java
  • python用法——Mixin

    在读werkzeugflask的源码中,经常能遇到类名中有mixin这个东西。这个东西的用法让我想到了java中的接口名有able的用法。今天我就来看了看这个mixin是什么东西。
    学习了python的都知道,python是支持多继承的,但是支不支持动态继承性质呢?在程序运行过程中,重定义类的继承,python是支持这种动态继承性质的。这也就是python中的mixin,在定义类过程中改变类的继承顺序,继承类。当某个模块不能修改时,通过mixin方式可以动态添加该类的方法,动态改变类的原有继承体系

    Mixin

    Mixin编程是一种开发模式,是一种将多个类中的功能单元的进行组合的利用的方式,这听起来就像是有类的继承机制就可以实现,然而这与传统的类继承有所不同。通常mixin并不作为任何类的基类,也不关心与什么类一起使用,而是在运行时动态的同其他零散的类一起组合使用
    使用mixin机制有如下好处:可以在不修改任何源代码的情况下,对已有类进行扩展;可以保证组件的划分;可以根据需要,使用已有的功能进行组合,来实现“新”类;很好的避免了类继承的局限性,因为新的业务需要可能就需要创建新的子类。
    在举例子之前,我们需要先熟悉几个关键字:

    1. __bases__: 返回一个元组,该元组元素是类的基类,如:

      class a:
      pass

      print(a.bases)
      (<class 'object'>,)
      可见a类继承了object

    2. __mro__: This attribute is a tuple of classes that are considered when looking for base classes during method resolution. 我的理解是 返回一个元组,该元组元素是该类的继承的类,当查询继承的时候会按从左到右的顺序。以刚刚的a类为例:

      print(a.mro)
      (<class 'main.a'>, <class 'object'>)

    例子

    在了解了以上的知识后,我来举个例子

    import types
    
    def mixin(pyClass, pyMixinClass, key=0):
        if key:
            pyClass.__bases__ = (pyMixinClass,) + pyClass.__bases__
        elif pyMixinClass not in pyClass.__bases__:
            pyClass.__bases__ += (pyMixinClass,)
        else:
            pass
    
    class test1:
        def test(self):
            print('In the test1 class!')
    
    class testMixin:
        def test(self):
            print('In the testMixin class!')
    
    class test2(test1, testMixin):
        def test(self):
            print('In the test2 class!')
    
    class test0(test1):
        pass
    
    if __name__ == '__main__':
        print(test0.__mro__)  #继承了test1,object
        test_0 = test0()
        test_0.test()  #调用test1的方法
        mixin(test0, testMixin, 1)  #优先继承testMixin类
        test__0 = test0()
        test__0.test()  #由于优先继承了testMixin类,所以调用testMixin类的方法
        print(test0.__mro__)
    
        print(test2.__mro__)
        mixin(test2, testMixin)
        print(test2.__mro__)
    

    输出结果:

    (<class '__main__.test0'>, <class '__main__.test1'>, <class 'object'>)
    In the test1 class!
    In the testMixin class!
    (<class '__main__.test0'>, <class '__main__.testMixin'>, <class '__main__.test1'>, <class 'object'>)
    (<class '__main__.test2'>, <class '__main__.test1'>, <class '__main__.testMixin'>, <class 'object'>)
    (<class '__main__.test2'>, <class '__main__.test1'>, <class '__main__.testMixin'>, <class 'object'>)
    

    注意本例的mixin方法,它的作用就是动态地给某个类(pyClass)通过继承的方式添加方法。
    要注意:pyClass.__bases__ = (pyMixinClass,) + pyClass.__bases__pyClass.__bases__ += (pyMixinClass,) 二者的顺序是不一样的。 还是用例子说明:

    a = (1,)
    a = a + (2,)
    print(a)
    #输出:(1,2)
    a = (3,) + a
    print(a)
    #输出:(3,1,2)
    

    __bases__返回的元组的元素顺序不一样会导致继承的顺序不一样,类会优先继承元组左边的类

  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/eric-nirnava/p/mixin.html
Copyright © 2011-2022 走看看