1. 程式人生 > >對於python 3.x與python2.x中新型類的繼承特性總結

對於python 3.x與python2.x中新型類的繼承特性總結

自己的 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中新型類的繼承特性總結