zoukankan      html  css  js  c++  java
  • python笔记63

    前言

    描述器定义
    描述器是一个类的类属性是另一个类的实例,另一个类中实现了__set____delete____get__方法之一。
    如有两个类A,B,类A中实现__set____delete____get__方法之一。类B中的一个属性为类A的实例

    描述器(descriptor)

    描述器会用到三个魔术方法__get__(), __set__() ,__delete__()
    方法使用如下:

    • object.__get__(self,instance,owner)
    • object.__set__(self,instance,value)
    • object.__delete__(self,instance)

    self指当前实例,调用者。instance是owner的实例。owner是属性所属的类。

    先看一段代码,B类中的类属性a是A类的实例A()

    # 作者-上海悠悠 QQ交流群:717225969 
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    class A(object):
    
        count = 0
    
        def __init__(self):
            self.name = "yoyo"
            self.age = 18
    
        def start(self):
            print("start1111111")
    
    
    class B(object):
        a = A()
    
        def __init__(self):
            self.colour = 'red'
            self.weight = 20
    
    print(B.a.name)
    b = B()
    print(b.a.name)
    

    上面的代码满足了第一个条件:一个类的类属性是另一个类的实例。
    接着再第一个类A里面添加一个__get__()方法

    # 作者-上海悠悠 QQ交流群:717225969 
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    class A(object):
    
        count = 0
    
        def __init__(self):
            self.name = "yoyo"
            self.age = 18
    
        def start(self):
            print("start1111111")
    
        def __get__(self, instance, owner):
            print('{}{}{}'.format(self, instance, owner))
    
    
    class B(object):
        a = A()
    
        def __init__(self):
            self.colour = 'red'
            self.weight = 20
    
    print(B.a.name)
    b = B()
    print(b.a.name)
    

    上面的代码运行就会抛AttributeError异常,出现错误的原因是:类A中定义__get__方法,那么类A就是描述器,原因是和类A中的__get__方法没return返回值

    加上·return self `后

    class A(object):
    
        count = 0
    
        def __init__(self):
            self.name = "yoyo"
            self.age = 18
    
        def start(self):
            print("start1111111")
    
        def __get__(self, instance, owner):
            # self指当前实例,调用者。Instance是owner的实例。Owner是属性所属的类。
            print('{}{}{}'.format(self, instance, owner))
            return self
    
    
    class B(object):
        a = A()
    
        def __init__(self):
            self.colour = 'red'
            self.weight = 20
    
    print(B.a.name)
    b = B()
    print(b.a.name)
    

    运行结果

    <__main__.A object at 0x000002027F9696A0>None<class '__main__.B'>
    yoyo
    <__main__.A object at 0x000002027F9696A0><__main__.B object at 0x000002027F969748><class '__main__.B'>
    yoyo
    

    B.a.name调用的时候,B类没有实例,所以instance实例为None

    实例属性不调用描述器

    如果B类的实例属性self.a是A的实例,此时不会触发A类__get__方法

    class A(object):
    
        count = 0
    
        def __init__(self):
            self.name = "yoyo"
            self.age = 18
    
        def start(self):
            print("start1111111")
    
        def __get__(self, instance, owner):
            print('{}{}{}'.format(self, instance, owner))
            return self
    
    
    class B(object):
        # a = A()
    
        def __init__(self):
            self.a = A()
            self.colour = 'red'
            self.weight = 20
    
    b = B()
    print(b.a.name)
    

    运行结果:yoyo
    此时不满足描述器的使用条件,不会触发

    参考资料:https://www.cnblogs.com/wangchunli-blogs/p/9949863.html
    参考资料:https://www.cnblogs.com/andy1031/p/10923834.html

  • 相关阅读:
    教你一步一步做无线点餐项目(登录篇)
    用Android中的ActionBar来实现分页Title栏滑块效果
    IIS处理brower的一个页面请求(www.test.com/SX?a=1)的处理流程
    [转载]物化视图——数据仓库手册
    [WEB系统中的设计模式(暂时放在这里,看不大懂)]mvc在web系统中的模式与应用
    ORACLE的分布式管理
    C#中 中 A==B && C==D ? E: F语法的一点问题
    delete 和 truncate
    prototype.js开发者手册
    【一个不错的oracle数据库诊断例子,值得学习一下】Oracle数据库诊断案例redo log日志组处于高激活状态
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15164355.html
Copyright © 2011-2022 走看看