記住如下幾點:python
直接子類化內置類型(如dict
,list
或str
)容易出錯,由於內置類型的方法一般會忽略用戶覆蓋的方法,不要子類化內置類型,用戶自定義的類應該繼承collections
模塊.函數
def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) # 錯誤案例 class AnswerDict(dict): def __getitem__(self, item): # 錯誤案例 return 42 import collections class DoppelDict2(collections.UserDict): # 正確案例 def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict2(collections.UserDict): # 正確案例 def __getitem__(self, item): return 42
多重繼承有關的另外一個問題就是:若是同級別的超類定義了同名屬性.Python
如何肯定使用哪一個?post
class DoppelDict(dict): def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict(dict): def __getitem__(self, item): return 42 import collections class DoppelDict2(collections.UserDict): def __setitem__(self, key, value): super().__setitem__(key, [value] * 2) class AnswerDict2(collections.UserDict): def __getitem__(self, item): return 42 class A: def ping(self): print('Ping:', self) class B(A): def pong(self): print('pong:', self) class C(A): def pong(self): print('PONG:', self) class D(B, C): def ping(self): super().ping() print('post-ping:', self) def pingpong(self): self.ping() super().ping() self.pong() super().pong() C.pong(self) if __name__ == '__main__': d = D() print(d.pong()) # 輸出來源於B print(C.pong(d)) #輸出來源於C 超類的方法均可以直接調用,此時要把實例做爲顯示參數傳入.
python
能區別調用的是哪一個方法,經過方法解析順序
>>> D.mro()
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
若想把方法調用委託給超類,推薦的方式是使用內置的super()函數.code
d.pingpong()
方法的解讀>>> self.ping()
Ping: <__main__.D object at 0x000002213877F2B0>
post-ping: <__main__.D object at 0x000002213877F2B0>
第一個調用的是self.ping()
,運行的是是D類的ping,方法.super().ping()
,跳過D類的ping
方法,找到A類的ping
方法.Ping: <__main__.D object at 0x000002213877F2B0>
self.pong()
方法,根據__mro__
,找到B類實現的pong
方法. pong: <__main__.D object at 0x000002213877F2B0>
super().pong()
,也是根據__mro__
,找到B類實現的pong
方法. pong: <__main__.D object at 0x000002213877F2B0>
C.pong(self)
,忽略了__mro__
,找到的是C類實現的pong
方法. PONG: <__main__.D object at 0x000002213877F2B0>