• 神奇的描述符(一):描述符协议的实现


    描述符通过描述符协议实现,任何实现或部分实现以下方法的类,都可以作为描述符使用。

    def __get__(self, instance, owner):
        ...
    
    def __set__(self, instance, value):
        ...
    
    def __delete__(self, instance):
        ....

    __get__ 方法接收三个参数:self为描述符实例自身; instance指访问属性所属的实例;owner指描述符实例附加到的类。

    __set__方法的前两个参数于__get__方法相同,第三个参数value为需要赋值的属性。

    __delete__方法的两个参数与__get__方法的前两个参数相同。

    定义一个简单的描述符,和描述符的托管类,进行测试

    class Descriptor:
    
        def __init__(self):
            pass
    
        def __get__(self, instance, owner):
            return self, instance, owner
    
        def __set__(self, instance, value):
            print(self, instance, value)
    
        def __delete__(self, instance):
            print(self, instance)
    
    
    class ClassA(object):
    
        descriptor = Descriptor()

    将ClassA实例化为对象a,并分别从实例、类层面读取描述符。

    观察执行结果:当通过实例访问时,instance为当前描述符托管的实例,而通过类访问时,instance为None。但是无论通过实例或类访问,owner都为描述符所属的类。

      # 实例化为对象a
        a = ClassA()
        # 从实例取值
        print(a.descriptor)
        # (<__main__.Descriptor object at 0x10c157438>, <__main__.ClassA object at 0x10c1574a8>, <class '__main__.ClassA'>)
        # 从类取值
        print(ClassA.descriptor)
        # (<__main__.Descriptor object at 0x10c157438>, None, <class '__main__.ClassA'>)

    对描述符的进行赋值,观察执行结果:可以发现第一个参数是描述符自身,第二个参数是描述符托管的实例,第三个参数是赋值给描述符的值

    # 对描述符进行赋值
    a.descriptor = 2
    # <__main__.Descriptor object at 0x10f0b1518><__main__.ClassA object at 0x10f0b1588> 2

    上面就是基本的描述符协议实现。

  • 相关阅读:
    leetCode 53. maximum subarray
    leetcode strStr()
    DCNN models
    1*1 的卷积核
    leetcode 14. longest common prefix
    springMVC接受json并打开新页面
    jsp取addFlashAttribute值深入理解即springMVC发redirect传隐藏参数
    hive安装教程本地模式
    poi excel超出65536行数限制自动扩展Invalid row number (65536) outside allow
    java 构造json对象数组
  • 原文地址:https://www.cnblogs.com/blackmatrix/p/6940550.html
Copyright © 2020-2023  润新知