python中的多繼承理解

  在python的多繼承中,父類的初始化順序遵循所謂方法解析順序(Method Resolution Order,MRO)的機制。python使用C3線性化算法來確定多繼承類的MRO:

  1. 目標:創建一個一致的線性繼承順序,同時保持父類的相對順序和子類優先原則。

  2. 子類優先:子類總是在其父類之前出現。從而子類可以重寫父類的方法或屬性。

  3. 從左到右的順序:在多繼承類時,指定的父類順序決定了它們在 MRO 中的優先級,會首先查找靠左的父類中的方法或屬性。

  4. 每個類只處理一次:確保在複雜的繼承體系中,每個類的方法或屬性只被考慮一次。

  關於如下代碼:

class Base1:
    def __init__(self, a):
        self.a = a
        print("Base1 initialized", a)

class Base2:
    def __init__(self, a):
        self.a = a
        print("Base2 initialized", a)

class Child(Base1, Base2):
    def __init__(self, a=1, b=2):
        super(Child, self).__init__(a)
        super(Base1, self).__init__(b)
        # Base1.__init__(self, a)
        # Base2.__init__(self, b)

c = Child()

  其中Child類多繼承了Base1和Base2,而Base2和Base2都需要傳入一個參數。代碼中列舉了兩種方式來初始化Child類:

  super:super(class, self).__init__(a)通過MRO的順序找到class在MRO中的下一個類來進行初始化。比如以上代碼中的super(Child, self).__init__(a),實際上是對Base1進行初始化,並保存到self中。super().__init__(a)與super(Child, self).__init__(a)效果相同。由於其中Base2是Base1在MRO中的下一個類,因此super(Base1, self).__init__(b)是將b傳入Base2對其進行初始化,並加載到self中。

  顯式初始化:文中註釋的代碼class.__init__(self, a),通過顯式的方式對父類class進行初始化,此時Base1.__init__(self, a)就是將a傳入Base1對其進行初始化。這種方式相較於super更容易理解,但需要自行控制好初始化的順序。此外,這種方式可以無需把父類寫在子類的類名括號中,也能實現對父類方法和屬性的繼承。當然這實際上等於複製了父類的屬性和方法,而並沒有繼承的關係,從而不能利用到繼承關係的一些python特性,如isinstance()方法的調用等。

  要查看某個類的MRO,可使用class.__mro__。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章