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的順序執行下去。

這個點,可以作爲面試題,考一下。實際工作中應該會遇到。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章