首页 > 编程语言 > 详细

对于python 3.x与python2.x中新型类的继承特性总结

时间:2019-03-21 18:38:33      阅读:156      评论:0      收藏:0      [点我收藏+]

(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中新型类的继承特性总结

原文:https://www.cnblogs.com/johnyang/p/10569063.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!