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


    (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]
    
    
    
    
    
    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    论知识共享平台
    网虫推荐firefox 4.0插件
    solaris下常见文件压缩/解压方式简单小结—待续中
    Nginx的启动,关闭,重启脚本
    怎样将oracle数据库用户锁住和解锁
    【APACHE】如何重启Apache?
    【MYSQL】解决Mysql直接登录问题(删除匿名用户)
    【PHP】关于set和get函数
    【JMAIL】jmail无法收邮件问题
    【PHP】Class ‘mysqli’ not found 问题
  • 原文地址:https://www.cnblogs.com/johnyang/p/10569063.html
Copyright © 2020-2023  润新知