python繼承實現的原理
阿新 • • 發佈:2017-10-04
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繼承實現的原理