python中super()的一些用法

在看python高級編程這本書的時候,在講到super的時候,產生了一些疑惑,super在python中的用法跟其餘的語言有一些不同的地方,在網上找了一些資料,發現基本上不多有文章能把個人疑惑講明白,其中這篇文章最有價值的地方是它講解了咱們平時對super的正確使用方法。python

首先看一段程序:編程

class A:
    def __init__(self):
        print("A", end=" ")
        super().__init__()


class E:
    def __init__(self):
        print("E", end=" ")
        super().__init__()


class B(E):
    def __init__(self):
        print("B", end=" ")
        super().__init__()


class D:
    def __init__(self):
        print("D", end=" ")
        super().__init__()


class C(A, B, D):
    def __init__(self):
        print("C", end=" ")
        A.__init__(self)
        D.__init__(self)
        B.__init__(self)


print("MRO:", [x.__name__ for x in C.__mro__])
print(C())

這段程序的打印結果是:ide

MRO: ['C', 'A', 'B', 'E', 'D', 'object']
C A B E D D B E D <__main__.C object at 0x1040340b8>

這段程序能夠簡單演示super()的用法,比較簡單的概念是__mro__,它告訴咱們某個類的繼承鏈信息,生成這個鏈的原則有兩條:wordpress

  • 在繼承關係中,全部的子類都在父類前邊
  • 若是出現衝突,則按照其__base__排序

要想理解上邊程序的打印結果,只須要知道super()其實它至關於super(cls, self),知道了這一點答案就很清晰了code

當執行A.__init__(self)這行代碼的時候,self指向了c實例對象,而後打印出A,當調用super().__init__()這行代碼的時候,實際至關於super(A, self).__init__()的調用, super(A, self)的會在self.__mro__中查找排在A後邊的類,這樣就實現了繼承鏈的調用了。對象

其實到了這裏,咱們基本上能猜到super()的實現原理了,雖然看上去它像沒傳入參數同樣,其實否則,若是咱們改變參數,找到的父類是不一樣的。排序

咱們把上邊代碼中的A稍微改變一下:繼承

class A:
    def __init__(self):
        print("A", end=" ")
        super(D, self).__init__()

那麼在這裏super(D, self)獲取的就是object了,所以打印結果是:get

MRO: ['C', 'A', 'B', 'E', 'D', 'object']
C A D B E D <__main__.C object at 0x1040340b8>

super()具備運行時特性,也就是說它的結果是動態計算出來的,利用這一點能夠寫出擴展性比較好的程序,同時,從編程語義也更符合生活習慣。目前可以總結的就是這樣。it

相關文章
相關標籤/搜索