Python 3 中的 super 和 __class__

子類裏訪問父類的同名屬性,而又不想直接引用父類的名字,由於說不定何時會去修改它,因此數據仍是隻保留一份的好。其實呢,還有更好的理由不去直接引用父類的名字,參見 Python’s super() considered super! | Deep Thoughts by Raymond Hettingerhtml

請輸入圖片描述

這時候就該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__ 名字。繼承


via lilydjwg.is-programmer.com圖片

相關文章
相關標籤/搜索