• super 使用以及原理


    用super也很久了,但是一直没有关注过他的原理。最近开始越来越多关注python更底层的实现和奇技淫巧。看到该方法越发使用得多所以也研究了一波

    平时单继承可能是我们遇到最多的情况。无非就是类似情况。

    class A(object):
        def __init__(self, a, b):
            print 'times gone away %s, %s' % (a, b)
    
    
    class B(A):
        def __init__(self, a, b):
            super(B, self).__init__(a, b)
    
    B(1, 2)
    times gone away 1, 2

    这个例子的类B继承了类A,然后在初始化方法里面调用了父类A的初始化方法并且传入了参数。

    其实我想说就这个 例子来看。。这样也可以

    class A(object):
        def __init__(self, a, b):
            print 'times gone away %s, %s' % (a, b)
    
    
    class B(A):
        pass
    
    
    B(1, 2)

    当然。调用父类初始化方法之后,我们依然在后面可以做一些 其他的操作,但是第二个例子就做不到了注意。

    super看上去 也可以通过直接写父类A.__init__(self, a, b)来实现但是,当我们遇到多继承的时候情况就有所改变。super可以帮忙利用方法解析顺序(Method Resolution Order, MRO)列表来寻找按顺序顺着父类。在多继承的情况下,初始化循序并非我们所想的自底向上。

    而是顺着mro列表从左到右。

    B.mro()   # or C.__mro__ or C().__class__.mro()
    [<class '__main__.B'>, <class '__main__.A'>, <type 'object'>]

    如上所示有三种方法查看该类的mro顺序。

    从上面返回的数组我们可以看到,从顺序上看是B到A到 object的继承关系。

    而super方法调用的本质是:

    def super(cls, inst):
        mro = inst.__class__.mro()
        return mro[mro.index(cls) + 1]

    我们将类名cls 和实例self传入,然后由mro找到自己的类位置并且+1 返回下个继承类调用位置。 而不是自底向上的寻找父类。 有这个公式可能就更容易明白了。

    preference的这篇文章举了一个 完整的多继承例子,但是我觉得 只要你理解了 python中寻找父类的方法不是自底向上 而是依赖mro算法的话,这样就不难理解了。

    Reference:

    https://segmentfault.com/a/1190000007426467  Python: 你不知道的 super

  • 相关阅读:
    计算机网路基础
    [python基础] python 2与python 3之间的区别 —— 默认中文字符串长
    [python基础] 同时赋值多个变量与变量值交换
    [python基础] python 2与python 3的区别,一个关于对象的未知的坑
    [python基础] python 2与python 3之间的区别 —— 不同数据类型间的运算
    [python基础] 浮点数乘法的误差问题
    关于HTMLTestRunner的中断与实时性问题
    [python自动化] 关于python无法修改全局变量的问题
    关于RFC2544中的Cut-Through和Store-and-Forward模式
    google filament pbr
  • 原文地址:https://www.cnblogs.com/piperck/p/6052962.html
Copyright © 2020-2023  润新知