子類裏訪問父類的同名屬性,而又不想直接引用父類的名字,由於說不定何時會去修改它,因此數據仍是隻保留一份的好。其實呢,還有更好的理由不去直接引用父類的名字,參見 Python’s super() considered super! | Deep Thoughts by Raymond Hettinger。html
這時候就該super()
登場啦——python
class A: def m(self): print('A') class B(A): def m(self): print('B') super().m() B().m()
固然 Python 2 裏super()
是必定要參數的,因此得這麼寫:segmentfault
class B(A): def m(self): print('B') super(B, self).m()
須要提到本身的名字。這個名字也是動態查找的,在這種狀況下替換第三方庫中的類會出問題。ide
`super()`` 很好地解決了訪問父類中的方法的問題。那麼,若是要訪問父類的父類(準確地說,是方法解析順序(MRO)中位於第三的類)的屬性呢?wordpress
好比,B 類是繼承 A 的,它重寫了 A 的 m 方法。如今咱們須要一個 C 類,它須要 B 類的一些方法,可是不要 B 的 m 方法,而改用 A 的。怎麼間接地引用到 A 的 m 方法呢?使用self.__class__
確定是不行的,由於 C 還可能被進一步繼承。spa
從文檔中我注意到,super 的實現是經過插入一個名爲 __class__
的名字來實現的(super 會從調用棧裏去查找這個 __class__
名字)。因此,就像文檔裏暗示的,其實能夠直接在定義方法時訪問 __class__
名字,它老是該方法被定義的類。繼續咱們的單字母類:code
class C(B): def m(self): print('C') # see the difference! print(__class__.__mro__) print(self.__class__.__mro__) __class__.__mro__[2].m(self) class D(C): def m(self): print('D') super().m() o = D() o.m()
會獲得:htm
D C (<class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>) (<class 't.D'>, <class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>) A
不過,PyPy 並不支持這個 __class__
名字。繼承