對於python 3.x與python2.x中新型類的繼承特性總結
阿新 • • 發佈:2019-03-21
自己的 a10 共同點 amd64 ini div 特殊 pass etc
(1)一般性繼承特性
""" 該文件對於python 3.x 及python 2.x的New-style 類的一般性繼承特性進行了說明和測試。 (1)實例的繼承特性:搜尋實例,類,超類: a.搜尋該實例的__class__(即該實例的類)的__mro__中的所有類的__dict__ b.如果在步驟a中,第一個找到的是相應的數據描述符,則調用並退出(找到後僅判斷是否為描述符,不再繼續往後找) c.否則,如果不是數據描述符,返回實例的__dict__中的值 d.否則,實例__dict__沒有,調用在a中找到的非數據描述符,或者返回在a中找到的值 (2)類的繼承特性:搜尋類,超類,元類: a.搜尋該類的__class__(即該類的元類)的__mro__中所有元類的__dict__ b.如果在步驟a中,第一個找到的相應的數據描述符,則調用並退出(找到後僅判斷是否為描述符,不再繼續往後找) c.否則,如果不是數據描述符,調用或返回在該類自己的__mro__中所有類的__dict__中的第一個找到的描述符或值 d.否則,調用在a中找到的非數據描述符,或者返回在a中找到的值 對於賦值繼承,實例繼承從上述a到c,不過b步驟改為__set__方法,c步驟為在繼承裏存儲 類繼承與一般性繼承特性一致,只有c步驟改為停止,儲存""" class desc: #數據描述符 def __get__(self,instance,owner): return (‘datadesc getting!‘) def __set__(self,instance,value): print (‘datadesc setting!‘,value) class Nondatadesc: #非數據描述符 def __get__(self,instance,owner):return (‘Nondatadesc getting‘) class a(type): data1=desc() #類繼承,第一個找到數據描述符 data2=‘only located in metaclass a‘ #類繼承,因為第一個找到的是該處,而該處又非數據描述符,而該類基類__dict__中又無,故返回該值 data10=Nondatadesc() #類繼承,找到非數據描述符,同上,最終返回該值 data11=Nondatadesc() #類繼承,第一個找到該處,但非數據描述符,在step c中,找到data11,故此處被截斷 class b: data1=‘b1‘ #類繼承,其值被描述符截斷 data3=desc() #類繼承,超類中找到的值 def __init__(self): self.data8=‘cannot be found‘ #實例繼承找不到該值,因為不在實例類的超類的__dict__中 data5=‘b5‘ #實例繼承,被前面的d中的描述符截斷 data7=‘found in superclass b‘ #實例繼承,返回僅能在b中找到的值 data6=desc() #實例繼承,於其類的超類中找到的數據描述符 data9=‘being intercepted by a.data9‘ #實例繼承,a中無描述符 data11=‘Fetched before data11 in class a‘ #類繼承,step c 返回該值,截斷元類 data12=Nondatadesc() #實例繼承中,最終返回非數據描述符 class d: data1=‘d1‘ data6=‘being found prior to b,so interceptting b"s desc‘ #實例繼承中,第一次找到,但不是desc,進入step c,實例中沒有data6,故最終返回該值 data5=desc() #實例繼承中,第一次找到的data5是描述符 data3=‘First meet d,so interceptting b"s desc‘ #類繼承中,第一次找到的daa3,不是 class c(d,b,metaclass=a): data1=‘c1‘ #類繼承中,其值被描述符截斷 data4=‘located in class c‘ #實例繼承,於其類中找到值 def __init__(self): self.data9=‘instance dict‘ #實例繼承步驟c中找到該值 # self.data5=‘instance data5‘ print(‘Test Starting‘.center(50,‘-‘)) import sys print(‘sys.verson=‘,sys.version) print(‘實例繼承測試‘.center(50,‘*‘)) x=c() print(‘x.data5‘,x.data5) print(‘x.data9‘,x.data9) print(‘x.data7‘,x.data7) print(‘x.data6‘,x.data6) print(‘x.data12‘,x.data12) x.data5=1 #觸發__set__方法 x.data9=2 # print(‘set x.data5=1->‘,x.data5) # x.data9=2 # print(‘set x.data9=2->‘,x.data9) try: x.data8 except AttributeError: print(‘impossible fetch‘) print(‘實例搜索路徑‘.center(50,‘*‘)) for cls in x.__class__.__mro__: for attr in cls.__dict__: if not attr.startswith(‘__‘): print(‘class %s--> attr %s‘%(cls.__name__,attr)) print(‘類繼承測試‘.center(50,‘*‘)) print(‘c.data1‘,c.data1) print(‘c.data3‘,c.data3) print(‘c.data2‘,c.data2) print(‘c.data10‘,c.data10) print(‘c.data11‘,c.data11) c.data1=1 #觸發__set__方法 c.data3=3
運行後:
------------------Test Starting------------------- sys.verson= 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] **********************實例繼承測試********************** x.data5 datadesc getting! x.data9 instance dict x.data7 found in superclass b x.data6 being found prior to b,so interceptting b"s desc x.data12 Nondatadesc getting datadesc setting! 1 impossible fetch **********************實例搜索路徑********************** class c--> attr data1 class c--> attr data4 class d--> attr data1 class d--> attr data6 class d--> attr data5 class d--> attr data3 class b--> attr data1 class b--> attr data3 class b--> attr data5 class b--> attr data7 class b--> attr data6 class b--> attr data9 class b--> attr data11 class b--> attr data12 **********************類繼承測試*********************** c.data1 datadesc getting! c.data3 First meet d,so interceptting b"s desc c.data2 only located in metaclass a c.data10 Nondatadesc getting c.data11 Fetched before data11 in class a datadesc setting! 1
(2)built-ins特殊情況
""" builtin 的繼承特性: (1)對於實例繼承:若是顯式調用,則首先搜索實例,否則搜索該實例的類,否則搜索實例類的超類; 若是隱式調用,則跳過實例,首先搜索該實例的類,否則搜索該實例類的超類。 (2)對於類繼承:若是顯示調用,則首先搜索該類,否則搜索該類的超類; 若是隱式調用,則跳過該類,首先搜索該類的元類(metaclass),否則搜索該元類的超類。 註意到2點:一是實例和類的共同點,即對於顯示調用,都是從自身層搜索,然後搜索自身的繼承層(實例繼承層是類, 類繼承層是超類;而隱式調用首先從自身的創建層(實例創建層是類,類創建層是元類),否則再搜索創建層的繼承層。 """ class a(type): def __str__(self): return ‘a‘ class b(type): pass class c(a): def __str__(self): return ‘c‘ class d(metaclass=a): pass class e(metaclass=a): def __str__(self): return ‘e‘ class f(metaclass=b): def __str__(self): return ‘f‘ class g(c): pass class h(d,e,metaclass=g):pass print(‘實例顯式繼承‘.center(50,‘*‘)) x=h() print(‘x.__str__:=>‘,x.__str__()) #實例無_str__,類無,超類d無,超類e有,返回‘e‘ x.__str__=lambda :‘lambda‘ print(‘Having set instance x"s __str__‘) print(‘x.__str__:=>‘,x.__str__()) #實例有__str__ print(‘實例隱式繼承‘.center(50,‘*‘)) print(‘str(x)‘,str(x)) #從類開始搜索,然後搜類的超類,找到e print(‘類顯式繼承‘.center(50,‘*‘)) print(‘h.__str__(h)‘,h.__str__(h)) #從類開始搜索,然後搜索類的超類,找到e print(‘類隱式繼承‘.center(50,‘*‘)) print(‘str(h)‘,str(h)) #從元類搜索,然後搜索元類的超類,找到c
**********************實例顯式繼承********************** x.__str__:=> e Having set instance x"s __str__ x.__str__:=> lambda **********************實例隱式繼承********************** str(x) e **********************類顯式繼承*********************** h.__str__(h) e **********************類隱式繼承*********************** str(h) c [Finished in 0.1s]
對於python 3.x與python2.x中新型類的繼承特性總結