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

  • 相关阅读:
    阿里知识图谱首次曝光:每天千万级拦截量,亿级别全量智能审核
    LSTM简介以及数学推导(FULL BPTT)
    深度学习算法索引(持续更新)
    学界 | Yann LeCun新作,中日韩文本分类到底要用哪种编码?
    Android 常见内存泄漏的解决方式
    集成支付宝支付
    【4.29安恒杯】writeup
    sdut 3-7 类的友元函数的应用
    Linux下libsvm的安装及简单练习
    iOS 使用腾讯地图显示用户位置注意事项
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15164355.html
Copyright © 2011-2022 走看看