1. 程式人生 > >python繼承實現的原理

python繼承實現的原理

spa ont 例如 計算 bar class border flow ges

python基礎——繼承實現的原理

1 繼承順序

技術分享

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 30 31 32 class A(object): def test(self): print(‘from A‘) class B(A): def test(self): print(‘from B‘) class C(A): def test(self): print
(‘from C‘) class D(B): def test(self): print(‘from D‘) class E(C): def test(self): print(‘from E‘) class F(D,E): # def test(self): # print(‘from F‘) pass f1=F() f1.test() print(F.__mro__) #只有新式才有這個屬性可以查看線性列表,經典類沒有這個屬性 #新式類繼承順序:F->D->B->E->C->A
#經典類繼承順序:F->D->B->A->E->C #python3中統一都是新式類 #pyhon2中才分新式類與經典類

  

2 繼承原理(python如何實現的繼承)

python到底是如何實現繼承的,對於你定義的每一個類,python會計算出一個方法解析順序(MRO)列表,這個MRO列表就是一個簡單的所有基類的線性順序列表,例如

1 2 >>> F.mro() #等同於F.__mro__ [<class ‘__main__.F‘>, <class ‘__main__.D‘>, <
class ‘__main__.B‘>, <class ‘__main__.E‘>, <class ‘__main__.C‘>, <class ‘__main__.A‘>,<br> <class ‘object‘>]

為了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止 

合並所有父類的MRO列表並遵循如下三條準則:
1.子類會先於父類被檢查
2.多個父類會根據它們在列表中的順序被檢查
3.如果對下一個類存在兩個合法的選擇,選擇第一個父類

3 子類中調用父類方法(super()方法)

子類繼承了父類的方法,然後想進行修改,註意了是基於原有的基礎上修改,那麽就需要在子類中調用父類的方法

方法一 父類名.父類方法()

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class People: def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age def walk(self): print(‘%s is walking‘%self.name) class Chinese(People): country=‘China‘ def __init__(self,name,sex,age,language=‘Chinses‘): People.__init__(self,name,sex,age) self.language=language def walk(self,x): pass c=Chinese(‘xiaojing‘,‘male‘,20) print(c.name,c.sex,c.age,c.language)

方法二 super()方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class People: def __init__(self,name,sex,age): self.name=name self.age=age self.sex=sex def walk(self): print(‘%s is walking‘%self.name) class Chinese(People): country=‘China‘ def __init__(self,name,sex,age,language=‘Chinese‘): super().__init__(name,sex,age) #super() 綁定 調用父類方法 self.language=language def walk(self,x): super().walk() print("---->子類的x",x) c=Chinese(‘EGG‘,‘male‘,‘20‘) c.walk(123)

不用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 #每個類中都繼承了且重寫了父類的方法 class A: def __init__(self): print(‘A的構造方法‘) class B(A): def __init__(self): print(‘B的構造方法‘) A.__init__(self) class C(A): def __init__(self): print(‘C的構造方法‘) A.__init__(self) class D(B,C): def __init__(self): print(‘D的構造方法‘) B.__init__(self) C.__init__(self) pass f1=D() print(D.__mro__) #python2中沒有這個屬性

當你使用super()函數時,Python會在MRO列表上繼續搜索下一個類。只要每個重定義的方法統一使用super()並只調用它一次,那麽控制流最終會遍歷完整個MRO列表,每個方法也只會被調用一次(註意註意註意:使用super調用的所有屬性,都是從MRO列表當前的位置往後找,千萬不要通過看代碼去找繼承關系,一定要看MRO列表

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #每個類中都繼承了且重寫了父類的方法 class A: def __init__(self): print(‘A的構造方法‘) class B(A): def __init__(self): print(‘B的構造方法‘) super(B,self).__init__() class C(A): def __init__(self): print(‘C的構造方法‘) super(C,self).__init__() class D(B,C): def __init__(self): print(‘D的構造方法‘) super(D,self).__init__() f1=D() print(D.__mro__) #python2中沒有這個屬性

python繼承實現的原理