日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

pythonsuper多重继承_小白都能理解的Python多继承

發布時間:2025/4/5 python 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pythonsuper多重继承_小白都能理解的Python多继承 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本文主要做科普用,在真實編程中不建議使用多重繼承,或者少用多重繼承,避免使代碼難以理解。

方法解析順序(MRO)

關于多重繼承,比較重要的是它的方法解析順序(可以理解為類的搜索順序),即MRO。這個跟類是新式類還是經典類有關,因為兩者的搜索算法不同。

在Python2及以前的版本,由任意內置類型派生出的類(只要一個內置類型位于類樹的某個位置),都屬于新式類;反之,不由任意內置類型派生出的類,則稱之為經典類

在Python3以后,沒有該區分,所有的類都派生自內置類型object,不管有沒有顯式繼承object,都屬于新式類。

對于經典類,多重繼承的MRO是深度優先,即從下往上搜索;新式類的MRO是采用C3算法(不同情況下,可表現為廣度優先,也可表現為深度優先)。

C3算法表現為深度優先的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

# C3-深度優先(D -> B -> A -> C)

class A:

var = 'A var'

class B(A):

pass

class C:

var = 'C var'

class D(B, C):

pass

if __name__ == '__main__':

# [, , , , ]

print(D.mro())

# A var

print(D.var)

復制代碼

C3算法表現為廣度優先的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

# C3-廣度優先(D -> B -> C -> A)

class A:

var = 'A var'

class B(A):

pass

class C(A):

var = 'C var'

class D(B, C):

pass

if __name__ == '__main__':

# [, , , , ]

print(D.mro())

# C var

print(D.var)

復制代碼

注:關于C3的詳細算法本文不討論,因為我也搞不懂(狗頭保命)

菱形多重繼承

其實菱形多重繼承上面已經有例子了,就是C3算法表現為廣度優先這個例子,畫起圖來是這樣的:

菱形多重繼承會導致的一個問題是A初始化了兩次,如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class A:

def say(self):

print("A say")

class B(A):

def say(self):

print("B say")

A.say(self)

class C(A):

def say(self):

print("C say")

A.say(self)

class D(B, C):

def say(self):

print("D say")

B.say(self)

C.say(self)

if __name__ == '__main__':

dd = D()

dd.say()

復制代碼

如果只想調用一次A,可使用super方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class A:

def say(self):

print("A say")

class B(A):

def say(self):

print("B say")

super().say()

class C(A):

def say(self):

print("C say")

super().say()

class D(B, C):

def say(self):

print("D say")

super().say()

if __name__ == '__main__':

print(D.mro())

dd = D()

dd.say()

復制代碼

_init_ 與 super()

1.如果父類有init方法,子類沒有,則子類默認繼承父類的init方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class A:

def __init__(self, a1, a2):

self.a1 = a1

self.a2 = a2

def say(self):

print("A say, a1: %s, a2: %s" % (self.a1, self.a2))

class B(A):

def say(self):

print("B say, a1: %s, a2: %s" % (self.a1, self.a2))

if __name__ == '__main__':

# 因為B繼承了A的init方法,所以也要傳入 a1,a2參數

bb = B("10", "100")

bb.say()

復制代碼

2.如果父類有init方法,子類也有,可理解為子類重寫了父類的init方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

class A:

def __init__(self, a1, a2):

self.a1 = a1

self.a2 = a2

def say(self):

print("A say, a1: %s, a2: %s" % (self.a1, self.a2))

class B(A):

def __init__(self, b1):

self.b1 = b1

def say(self):

print("B say, b1: %s" % self.b1)

if __name__ == '__main__':

# 此處B重寫了A的init方法,所以只需要傳入b1參數,也沒有擁有a1,a2屬性

bb = B("10")

bb.say()

復制代碼

3.對于第二點,為了能使用或者擴展父類的行為,更常見的做法是在重寫init方法的同時,顯示調用父類的init方法(意味傳的參數要變成3個)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

# 三種寫法

class A:

def __init__(self, a1, a2):

self.a1 = a1

self.a2 = a2

def say(self):

print("A say, a1: %s, a2: %s" % (self.a1, self.a2))

class B(A):

def __init__(self, b1, a1, a2):

# 第一種寫法: Python2的寫法

# super(B, self).__init__(a1, a2)

# 第二種寫法(推薦):Python3的寫法,與第一種等價

super().__init__(a1, a2)

# 第三種寫法:與前兩種等價,不過這種需要顯示調用基類,而第二種不用

# A.__init__(self, a1, a2)

self.b1 = b1

def say(self):

print("B say, a1: %s, a2: %s, b1: %s" % (self.a1, self.a2, self.b1))

if __name__ == '__main__':

# 此處B重寫了A的init方法,所以只需要傳入b1參數,也沒有擁有a1,a2屬性

bb = B("10", "100", "1000")

bb.say()

復制代碼

最后的提醒

注意 __init__ 方法不要寫錯,避免寫成__ini__或者其他的,因為兩個是在太像,出了問題很難排查(坑過兩次)。

參考

python 多重繼承的事

當心掉進Python多重繼承里的坑

總結

以上是生活随笔為你收集整理的pythonsuper多重继承_小白都能理解的Python多继承的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。