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

  • 相关阅读:
    报名用户主题看板
    有效线索主题看板 阿善有用 清洗转换具体怎么做
    意向客户主题看板 阿善看到 阿善用到 拉链表
    数据库建模 全量表导入
    git 阿善有用
    IDEA+git+码云
    Cloudera Manager的基本使用 阿善没用
    cloudera manager报错解决方案
    java-多态简述及实例
    java-简述接口及实例
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15164355.html
Copyright © 2011-2022 走看看