class A: def who(self): print('A', end='') class B(A): def who(self): super(B, self).who() print('B', end='') class C(A): def who(self): super(C, self).who() print('C', end='') class D(B, C): def who(self): super(D, self).who() print('D', end='') item = D() item.who()
點(diǎn)評(píng):
這道題考查到了兩個(gè)知識(shí)點(diǎn):
1. Python中的MRO(方法解析順序)。
在沒有多重繼承的情況下,向?qū)ο蟀l(fā)出一個(gè)消息,如果對(duì)象沒有對(duì)應(yīng)的方法,那么向上(父類)搜索的順序是非常清晰的。
如果向上追溯到object類(所有類的父類)都沒有找到對(duì)應(yīng)的方法,那么將會(huì)引發(fā)AttributeError異常。
但是有多重繼承尤其是出現(xiàn)菱形繼承(鉆石繼承)的時(shí)候,向上追溯到底應(yīng)該找到那個(gè)方法就得確定MRO。
Python 3中的類以及Python 2中的新式類使用C3算法來確定MRO,它是一種類似于廣度優(yōu)先搜索的方法;
Python 2中的舊式類(經(jīng)典類)使用深度優(yōu)先搜索來確定MRO。在搞不清楚MRO的情況下,可以使用類的mro方法或__mro__屬性來獲得類的MRO列表。
2. super()函數(shù)的使用。在使用super函數(shù)時(shí),可以通過super(類型, 對(duì)象)來指定對(duì)哪個(gè)對(duì)象以哪個(gè)類為起點(diǎn)向上搜索父類方法。
所以上面B類代碼中的super(B, self).who()表示以B類為起點(diǎn),向上搜索self(D類對(duì)象)的who方法,所以會(huì)找到C類中的who方法,因?yàn)镈類對(duì)象的MRO列表是D --> B --> C --> A --> object。 ACBD