python中super方法的注意点

之前,碰到一个很有意思的问题,调用super之后,并没有按照预期执行。大概是如下的:

#!/usr/bin/env python
# -*- coding=utf-8 -*-


class A(object):

    def __init__(self):
        print(type(self).mro())

    def test(self):
        print('A.test')
        print(id(self))
        print('A.test.end')


class B(A):
    def test(self):
        print('b.test')
        print(id(self))
        super(B, self).test()
        print('b.test.end')


class C(A):
    def test(self):
        print('c.test')
        print(id(self))
        super(C, self).test()
        print('c.test.end')


class D(B, C):
    def test(self):
        print('D.test')
        print(id(self))
        super(D, self).test()
        print('d.test.end')

D().test()

运行结果如下:

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
D.test
4358651520
b.test
4358651520
c.test
4358651520
A.test
4358651520
A.test.end
c.test.end
b.test.end
d.test.end

可以看出,super的执行的顺序是Dstart->Bstart->Cstart->Astart->Aend->Cend->Bend>Dend,这个顺序与D的mro顺序一致。

这是由于super的实现导致的,其原理如下:

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

super会在inst的mro中查找到匹配到cls的下一个类,因此,从结果中也可以看到,super(x,self)中的self是同一个实例,因此,调用super时会按照mro的顺序执行下去。

这个点,可以作为面试题,考一下。实际工作中应该会遇到。

猜你喜欢

转载自blog.csdn.net/qq_39469761/article/details/81228479
今日推荐