Fluent-Python-第20章:属性描述符

news/2025/2/15 14:43:51/文章来源:https://www.cnblogs.com/super-zzh/p/18716905

属性描述符

学会描述符之后,不仅有更多的工具集可用,还会对 Python 的运作方式有更深入的理解,并由衷赞叹 Python 设计的优雅。
——Raymond Hettinger, Python 核心开发者和专家

本章的话题是描述符。
描述符是实现了特定协议的类,这个协议包括 __get____set__、和 __delete__ 方法。

有了它,我们就可以在类上定义一个托管属性,并把所有对实例中托管属性的读写操作交给描述符类去处理。

# 描述符示例:将一个属性托管给一个描述符类
class CharField:                       # 描述符类def __init__(self, field_name):self.field_name = field_namedef __get__(self, instance, storage_cls):print('__get__', instance, storage_cls)if instance is None:            # 直接在类上访问托管属性时,instance 为 Nonereturn selfreturn instance[self.field_name]def __set__(self, instance, value):print('__set__', instance, value)if not isinstance(value, str):raise TypeError('Value should be string')instance[self.field_name] = valueclass SomeModel:                         # 托管类name = CharField('name')             # 描述符实例,也是托管类中的托管属性def __init__(self, **kwargs):self._dict = kwargs              # 出巡属性,用于存储属性def __getitem__(self, item):return self._dict[item]def __setitem__(self, item, value):self._dict[item] = valueprint(SomeModel.name)
d = SomeModel(name='some name')
print(d.name)
d.name = 'another name'
print(d.name)
try:d.name = 1
except Exception as e:print(repr(e))
__get__ None <class '__main__.SomeModel'>
<__main__.CharField object at 0x063AF1F0>
__get__ <__main__.SomeModel object at 0x063AF4B0> <class '__main__.SomeModel'>
some name
__set__ <__main__.SomeModel object at 0x063AF4B0> another name
__get__ <__main__.SomeModel object at 0x063AF4B0> <class '__main__.SomeModel'>
another name
__set__ <__main__.SomeModel object at 0x063AF4B0> 1
TypeError('Value should be string')

描述符的种类

根据描述符上实现的方法类型,我们可以把描述符分为覆盖型描述符非覆盖型描述符

实现 __set__ 方法的描述符属于覆盖型描述符,因为虽然描述符是类属性,但是实现 __set__ 方法的话,会覆盖对实例属性的赋值操作。
而没有实现 __set__ 方法的描述符是非覆盖型描述符。对实例的托管属性赋值,则会覆盖掉原有的描述符属性,此后再访问该属性时,将不会触发描述符的 __get__ 操作。如果想恢复原有的描述符行为,则需要用 del 把覆盖掉的属性删除。

具体可以看官方 Repo 的例子。

描述符的用法建议

  • 如果只想实现一个只读描述符,可以考虑使用 property 而不是自己去实现描述符;
  • 只读描述符必须有 __set__ 方法,在方法内抛出 AttributeError,防止属性在写时被覆盖;
  • 用于验证的描述符可以只有 __set__ 方法:通过验证后,可以修改 self.__dict__[key] 来将属性写入对象;
  • 仅有 __get__ 方法的描述符可以实现高效缓存;
  • 非特殊的方法可以被实例属性覆盖。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884257.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lesson-9-a-story-on-cyclic-imports

前言 模块(Module)是我们用来组织 Python 代码的基本单位。很多功能强大的复杂站点,都由成百上千个独立模块共同组成。 虽然模块有着不可替代的用处,但它有时也会给我们带来麻烦。比如,当你接手一个新项目后,刚展开项目目录。第一眼就看到了攀枝错节、难以理解的模块结构…

KUKA库卡机器人KRC5控制器维修全过程

库卡工业机器人作为现代工业中的重要设备,KUKA机械手KRC5控制柜作为其核心部件,对机器人的正常运行起着至关重要的作用。 【一】KUKA机械手KRC5控制柜的结构分析 库卡工业机器人控制柜主要由电源模块、控制模块、驱动模块、传感器模块等组成。这些模块协同工作,确保机器人的…

萌新刚入坑

markdddown学习 标题 三级标题 四级标题 字体 Hello,World! Hello,World! Hello,World! Hello,World! 引用 选择狂神说java,走上人生巅峰 分割线图片超链接 点击跳转到狂神博客 列表A CABC表格名字 性别 生日张三 男 1997.1.1代码 hello public

Retrieval-Augmented Generation

大模型的商业化落地挑战 更好地控制大模型生成:生成优点:内容的多样性、创造性 缺点:存在不可控制的问题检索优点:可控 缺点:内容具有局限性结合两者:检索增强生成(Retrieval-Augmented Generation, RAG) 案例:金融智能客服系统的几种思路专家系统 生成式模型 大模型检索…

沁恒CH32V307EVT-R1开发板使用说明

首先下载官方的资料:CH32V307EVT.ZIP - 南京沁恒微电子股份有限公司 解压后CH32V307EVT\EVT\EXAM里的就是官方的示例代码,CH32V307EVT\EVT\PUB下面的是文档 CH32V307EVT/EVT/PUB/CH32V30x评估板说明书.pdf:是各个开发板的介绍 CH32V307EVT/EVT/PUB/CH32V30xSCH.pdf:是开发板…

YASKAWA机器人NX100控制柜无法启动维修

当YASKAWA机器人NX100控制柜无法启动时,这无疑是一个典型的机器人故障。首先要做的是对故障进行初步的排查。检查电源连接是否正常,是否存在松动或者断电的情况。这可能是最常见的原因,但也容易被忽视。同时,观察控制柜的指示灯状态,如果指示灯完全不亮,可能是电源供应模…

微信小程序ReferenceError:xxx is not defined报错解决办法

我在开发的过程中想要打印adressInfo的数据信息,却发现一直报错,而AppData里显示adressInfo是被成功赋值的。 那么问题就出现在了"console.log(adressInfo)"这条语句中 只需要把"adressInfo"改为"this.data.adressInfo"报错问题就能够成功解决…

蒙德里安的梦想(状态压缩)

1.首先就是每列状态的表示,如果该列有横着的方块就用1,表示否则就用零,一共n行最多有n个一就是2^n-1最少0个一就是0,所以0<=i<n;j表示i位移的个数,i最多n位所以最多位移n-1位来检验i每一位,如果是1就检验cnt来检验是否有连续奇数个0,最后还要再检验一次来检验高位…

原子物理之光电效应

光电效应的原理、实验细节和动态分析普朗克能量子 定义 普朗克认为,带电微粒(高中阶段主要研究电子)辐射或吸收能量的时候,只能辐射或吸收某个最小能量值的整数倍。这个不可再分的最小能量值就叫做能量子。 通常的,我们认为光子也是一种能量子。 能量子大小 公式: \[ε=…

钜泉代理商,HT6453钜泉M4电能专用MCU,集成1M Flash、32位定时器、CAN总线

HT6453微控制器内部集成了:32位ARMCortex-M4F处理器,多个16位和32位的定时器,DMA控制器,SPI通信接口,I2C通信接口,USART/UART通信接口,SDIO接口,CAN总线控制器,外部存储控制器XMC,USB2.0全速设备接口,HICK自动时钟校准ACC,12位ADC,12位DAC和PVM模块等外设。大量的…

项目管理5阶段

目录背景和价值参考资料 背景和价值 项目的生命周期共包括5个部分,因为每个部分都会包含至少两个相对独立又相互联系的过程,所以又称“过程组”​。每个过程组的主要工作如下: 启动:确立项目的合法地位和总体要求(目标)​,宣布项目正式立项(上马)​。 规划:编制项目计…

图解支付账务系统核心设计

在金融科技领域,支付账务系统的设计和实现是构建高效、安全支付平台的关键。本文深入探讨了支付账务系统的核心设计,从账户管理、记账处理到清结算与会计服务,为读者揭示了支付账务系统设计的复杂性和重要性。通过详细的图解和案例分析,文章为支付系统设计提供了宝贵的理论…