Python 描述符协议(descriptor protocol)

Python 描述符协议(descriptor protocol)

参考:

  1. Clean Code in Python Refactor your legacy codebase by Mariano Anaya (z-lib.org), Chapter 6
  2. Python document: Descriptor HowTo Guide
  3. Python implementing descriptors

描述符协议

Simple example

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class DescriptorClass(object):
    value = 42

    def __get__(self, instance, owner):
        if instance is None:
            return f"{self.__class__.__name__}.{owner.__name__}"

        return f"value for {instance}"


class ClientClass(object):
    descriptor = DescriptorClass()


def main():
    client = ClientClass()
	
    # output: DescriptorClass.ClientClass
    print(ClientClass.descriptor)
    
    # output: value for <__main__.ClientClass object at 0x...>
    print(client.descriptor)


if __name__ == '__main__':
    main()


__get__(self, instance, owner)

当我们希望获取描述符的值时, 该方法会被调用. 方法参数解释如下:

self : 表示 descriptor 对象本身

instance : 当 descriptor 被实例调用时, 表示该实例, 如果是被类调用, 则该参数为 None

owner : 表示 instance 参数的所属的类

因为 descriptor 是作为类的属性存在的, 所以是可以通过 ClientClass.descriptor 这种方式调用的. __get__ 的接口会看起来显得如此奇怪的原因就是为了保证不管是通过实例调用(obj.descriptor)还是通过类调用(Class.descriptor) , 该接口都能正常工作.

通常来说, 除非我们希望对 owner 进行一些操作, 否则当 instanceNone 时, 一般返回描述符本身比较好.

__set__(self, instance, value)

当我们对描述符进行赋值操作时, 该方法会被调用. self 参数和 instance 参数同前, value 参数则表示被赋值的具体值.

当我们通过 client.descriptor = "value" 这样的调用方式对描述符进行赋值时, 如果描述符定义了 __set__ 方法,则会调用描述符的 __set__ 方法进行赋值, 此时 value 参数被设为 “value” . 如果描述符没有定义

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值