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

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

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

 

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

 

posted @ 2017-07-13 15:46  BlackMatrix  阅读(407)  评论(0编辑  收藏  举报