流畅的Python(二十)-属性描述符

本文详细介绍了Python中的描述符(Descriptor)机制,包括描述符的使用、不同版本的LineItem类演示了如何通过描述符实现属性的自动存储、验证和覆盖规则,以及覆盖与非覆盖描述符的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、核心要义

描述符是对多个属性运用相同存取逻辑的一种方式。其是实现了特定协议的类,常见协议包括__get__,__set__,__delete__方法。上一章介绍的property类就实现了完整的描述符协议。

二、代码示例

1、LineItem类第3版

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/3/17 12:46
# @Author  : Maple
# @File    : 01-LineItem类第3版.py
# @Software: PyCharm

"""一个简单的描述符类"""


class Quantity:

    def __init__(self,storage_name):
        self.storage_name = storage_name

    def __set__(self, instance, value):
        if value > 0:
            instance.__dict__[self.storage_name] = value
        else:
            raise ValueError('value must be >0')


class LineItem:

    weight = Quantity('weight')
    price = Quantity('price')

    def __init__(self,description,weight,price):
        self.description = description
        # 这里赋值的时候,会访问描述符类的set方法
        self.weight = weight
        self.price = price

    def subtotal(self):
        return self.weight * self.price

    def __repr__(self):
        return 'LineItem =({},{},{})'.format(self.description,self.weight,self.price)

if __name__ == '__main__':

    # 1.传入正常的值
    com = LineItem('Computer',10,2000)
    print(com) # LineItem =(Computer,10,2000)

    # 2.weight负值测试
    try:
        com3 = LineItem('Computer', -10, 1000)
    except ValueError as e:
        print(e)  # value must be >0

2、LineItem类第4版

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/3/17 9:36
# @Author  : Maple
# @File    : 02-LineItem类第4版.py
# @Software: PyCharm

"""自动获取存储属性的值"""

class Quantity:

    __counter = 0

    def __init__(self):
        cls = self.__class__
        prefix = cls.__name__
        index = cls.__counter
        self.storage_name = '_{}#{}'.format(prefix,index)
        cls.__counter += 1

    def __get__(self, instance, owner):
        if instance is None:
            # 通过托管类(此例中的LineItem)直接访问类属性时(此例中的weight和price时,instance为None,如果直接执行getattr,会报错
            # 因此在此进行一下处理:直接返回描述符类
            return self
        else:
            ret
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值