(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]