之前,碰到一個很有意思的問題,調用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的順序執行下去。
這個點,可以作爲面試題,考一下。實際工作中應該會遇到。