Python - 面向對象編程 - 使用 super() 的一些注意事項


super() 詳解

https://www.cnblogs.com/poloyy/p/15223443.html

 

多繼承中使用 super()

class A:
    def test(self):
        print("AAA")


class B:
    def test(self):
        print("BBB")


class C(A, B):
    def test(self):
        print("CCC")
        super().test()

c = C()
c.test()


# 輸出結果
CCC
AAA

根據 MRO,super() 很明顯調用的是 A 類的 test() 方法

假設想調用 B 類的 test() 方法,要怎么做呢?

 

方式

class C(A, B):
    def test(self):
        print("CCC")
        super().test()
        B.test(self)


# 輸出結果
CCC
AAA
BBB

通過 父類名.方法名() 即可,但這樣和 super() 混用,不是一個好編碼習慣,具體看下面

 

混用super() 和 顯示類調用

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


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


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


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



# 輸出結果
MRO: ['C', 'A', 'B', 'object']
C A B B 

B 類的 __init__() 方法被調用了兩次

 

為什么呢?

  • C 類里面又通過 B.__init__() 顯式的調用了一次
  • 從 MRO 可以看到,A 類后面跟的是 B 類,所以 A 類的 super() 會調用 B 類
  • 一共調用了兩次

 

如何避免

  • 在多繼承場景中,super() 的使用必須一致,即在類的層次結構中,要么全部使用 super(),要么全不用!堅決不混用
  • 繼承父類時應該查看類的層次結構,就是使用類的 __mro__  屬性,或者 mro() 方法查看相關類的 MRO

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM