人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)
Python中的super()面向?qū)ο缶幊?/h1>
發(fā)布日期:2022-01-25 18:49 | 文章來源:腳本之家

Python super()面向?qū)ο缶幊?br/>

一、為什么要用 super()

當(dāng)子類重寫了父類方法時,又想調(diào)用父類的同名方法時,就需要用到 super()

二、什么是 super

  • 在 Python 中,super 是一個特殊的類
  • super() 就是使用 super 類創(chuàng)建出來的對象
  • 實際應(yīng)用的場景:子類在重寫父類方法時,調(diào)用父類方法

三、繼承中使用 super

1、實例方法使用 super

類圖

實際代碼

class A:
 def __init__(self):
  self.n = 1
 def add(self, m):
  print(f'AAA [self] is {id(self)}')
  print(f'AAA [self.n] is {self.n}')
  self.n += m

class B(A):
 def __init__(self):
  self.n = 100
 # 重寫父類方法
 def add(self, m):
  # 子類特有代碼
  print(f'BBB [self] is {id(self)}')
  print(f'BBB [self.n] is {self.n}')
  # 調(diào)用父類方法
  super().add(m)
  self.n += m

b = B()
b.add(2)
print(b.n)
 
# 輸出結(jié)果
BBB [self] is 4489158560
BBB [self.n] is 100
AAA [self] is 4489158560
AAA [self.n] is 100
104

super().add() 的確調(diào)用了父類方法
重點:此時父類方法的 self 并不是父類實例對象,而是子類實例對象

2、構(gòu)造方法使用 super

class Animal:
 def __init__(self, name):
  self.name = name
 def prints(self):
  print("Animale name is ", self.name)

class Dog(Animal):
 def __init__(self, name, age):
  # 調(diào)用父類的 init 構(gòu)造方法
  super(Dog, self).__init__(name)
  self.age = age
 def prints(self):
  # 調(diào)用父類的方法
  super(Dog, self).prints()
  print("Dog age is ", self.age)

dog = Dog("小汪", 10)
dog.prints()
 
# 輸出結(jié)果
Animale name is  小汪
Dog age is  10

這里用了 super(子類名, self) ,和上面的 super() 是一樣效果

調(diào)用父類方法有兩種方式

  • super().父類方法()
  • super(子類名, self).父類方法()

其實還有第三種

在 Python 2.x 的時候,如果需要調(diào)用父類的方法,還可以用

父類名.方法(self)

  • 這種方式,Python 3.x 還是支持的
  • 過不不推薦,因為父類名發(fā)生變化的話,方法調(diào)用位置的類名也要同步修改

通過父類名調(diào)用父類方法(不推薦)

class Animal:
 def __init__(self, name):
  self.name = name
 def prints(self):
  print("Animale name is ", self.name)

class Dog(Animal):
 def __init__(self, name, age):
  # 調(diào)用父類的 init 構(gòu)造方法
  Animal.__init__(self, name)
  self.age = age
 def prints(self):
  # 調(diào)用父類的方法
  Animal.prints(self)
  print("Dog age is ", self.age)

dog = Dog("小汪", 10)
dog.prints()

# 輸出結(jié)果
Animale name is  小汪
Dog age is  10

通過父類名調(diào)用的這種方式,是需要傳 self 參數(shù)的哦

溫馨提示:
在開發(fā)時, 父類名.方法() , super().方法() 兩種方式不要混用哈

靈魂拷問一:既然已經(jīng)重寫了子類的構(gòu)造方法,為什么還要去調(diào)用 super?
子類需要重寫父類方法來實現(xiàn)子類獨有的功能,但同時又需要依賴父類方法來完成某些邏輯

實際栗子

  • 在實現(xiàn)多線程的時候(后面會詳細(xì)展開說多線程)
  • 父類 Thread 的構(gòu)造方法包含了很多邏輯代碼
  • 子線程雖然需要實現(xiàn)子類獨有功能,但仍需父類方法來處理其他邏輯

from threading import Thread

class MyThread(Thread):
 def __init__(self, name):
  # 1、實現(xiàn)子類獨有功能
  print("子類線程 %s" % name)
  # 2、需要依賴父類方法完成其他功能
  super().__init__(name=name)

四、多繼承中使用 super

類圖

實際代碼

# 多繼承
class Animal:
 def __init__(self, animalName):
  print(animalName, 'is an animal.')

# Mammal 繼承 Animal
class Mammal(Animal):
 def __init__(self, mammalName):
  print(mammalName, 'is a mammal.')
  super().__init__(mammalName)

# CannotFly 繼承 Mammal
class CannotFly(Mammal):
 def __init__(self, mammalThatCantFly):
  print(mammalThatCantFly, "cannot fly.")
  super().__init__(mammalThatCantFly)

# CannotSwim 繼承 Mammal
class CannotSwim(Mammal):
 def __init__(self, mammalThatCantSwim):
  print(mammalThatCantSwim, "cannot swim.")
  super().__init__(mammalThatCantSwim)

# Cat 繼承 CannotSwim 和 CannotFly
class Cat(CannotSwim, CannotFly):
 def __init__(self):
  print('I am a cat.');
  super().__init__('Cat')

# Driver code
cat = Cat()
print('')
bat = CannotSwim('Bat')
 
# 輸出結(jié)果
I am a cat.
Cat cannot swim.
Cat cannot fly.
Cat is a mammal.
Cat is an animal.
Bat cannot swim.
Bat is a mammal.
Bat is an animal.

好像挺奇怪的,從輸出結(jié)果看,為什么 CannotSwim 類里面的 super().__init__() 調(diào)用的是 CannotFly 類里面的方法呢?不是應(yīng)該調(diào)用 CannotSwim 的父類 Mamal 的方法嗎?

靈魂拷問二:super 的執(zhí)行順序到底是什么?

  • 其實 super() 并不一定調(diào)用父類的方法
  • super() 是根據(jù)類的 MRO 方法搜索順序來決定調(diào)用誰的
  • super() 真正調(diào)用的是 MRO 中的下一個類,而不一定是父類
  • 當(dāng)然,這種情況只會出現(xiàn)在多繼承

先來看看 Cat 的 MRO

print(Cat.__mro__)
(<class '__main__.Cat'>, <class '__main__.CannotSwim'>, <class '__main__.CannotFly'>, <class '__main__.Mammal'>, <class '__main__.Animal'>, <class 'object'>)

從 Cat 的 MRO 可以看到

  • CannotSwim 后面跟的是 CannotFly 而不是 Mamal
  • 所以 CannotSwim 類里面的 super() 會調(diào)用 CannotFly 里面的方法

多繼承的栗子二

實際代碼

class A:
 def __init__(self):
  self.n = 2
 def add(self, m):
  # 第四步
  # 來自 D.add 中的 super
  # self == d, self.n == d.n == 5
  print('self is {0} @AAA.add'.format(self))
  self.n += m
  # d.n == 7

class C(A):
 def __init__(self):
  self.n = 4
 def add(self, m):
  # 第三步
  # 來自 B.add 中的 super
  # self == d, self.n == d.n == 5
  print('self is {0} @CCC.add'.format(self))
  # 等價于 suepr(C, self).add(m)
  # self 的 MRO 是 [D, B, C, A, object]
  # 從 C 之后的 [A, object] 中查找 add 方法
  super().add(m)
  # 第五步
  # d.n = 7
  self.n += 4
  # d.n = 11

class B(A):
 def __init__(self):
  self.n = 3
 def add(self, m):
  # 第二步
  # 來自 D.add 中的 super
  # self == d, self.n == d.n == 5
  print('self is {0} @BBB.add'.format(self))
  # self 的 MRO 是 [D, B, C, A, object]
  # 從 B 之后的 [C, A, object] 中查找 add 方法
  # 從 C 找 add 方法
  super().add(m)
  # 第六步
  # d.n = 11
  self.n += 3
  # d.n = 14

class D(B, C):
 def __init__(self):
  self.n = 5
 def add(self, m):
  # 第一步
  print('self is {0} @DDD.add'.format(self))
  # self 的 MRO 是 [D, B, C, A, object]
  # 從 D 之后的 [B, C, A, object] 中查找 add 方法
  # 從 B 找 add 方法
  super().add(m)
  # 第七步
  # d.n = 14
  self.n += 5
  # self.n = 19

d = D()
d.add(2)
print(d.n)
 

先看看 D 類的 MRO

print(D.__mro__)
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

輸出結(jié)果

self is <__main__.D object at 0x10c14a190> @DDD.add
self is <__main__.D object at 0x10c14a190> @BBB.add
self is <__main__.D object at 0x10c14a190> @CCC.add
self is <__main__.D object at 0x10c14a190> @AAA.add
19

調(diào)用順序的確是 D、B、C、A

執(zhí)行順序

class D(B, C): class B(A):class C(A): class A:
def add(self, m): def add(self, m):def add(self, m): def add(self, m):
super().add(m)  1.--->  super().add(m) 2.--->  super().add(m)  3.--->  self.n += m
 self.n += 5<------6. self.n += 3 <----5. self.n += 4  <----4. <--|
(14+5=19)(11+3=14)  (7+4=11) (5+2=7)
 

執(zhí)行順序圖


到此這篇關(guān)于Python super()面向?qū)ο缶幊痰奈恼戮徒榻B到這了,更多相關(guān)Python super()內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部