当前位置: 首页 > news >正文

Effective Python 第50条:用__set_name__给类属性加注解

Effective Python 第50条:用__set_name__给类属性加注解

  • 描述符基础
  • 实践示例:带验证的属性
  • 高级应用:自动生成文档
  • 实际应用场景
  • 注意事项
  • 结论

在Python编程中,描述符(descriptor)是一种强大的特性,它允许我们自定义属性访问的行为。__set_name__方法是描述符协议的一部分,它在Python 3.6中引入,用于在类创建时自动调用,以便描述符可以获取它所描述的属性名称。本文将深入探讨如何使用__set_name__来为类属性添加注解,实现更优雅的代码结构。

描述符基础

描述符是一个实现了至少三个方法之一(__get____set____delete__)的对象。当一个类中的属性使用了描述符时,Python会自动调用这些方法来获取、设置或删除属性值。

__set_name__方法在描述符被赋值给类属性时调用,它接收两个参数:所有者类(owner)和属性名(name)。这使得描述符可以知道它所描述的属性名称,从而可以更灵活地处理属性。

实践示例:带验证的属性

让我们创建一个带验证功能的描述符,使用__set_name__来存储属性名称:

class Validated:def __init__(self, validation_function):self.validation_function = validation_functionself.name = None  # 将在__set_name__中设置def __set_name__(self, owner, name):self.name = namedef __get__(self, instance, owner):if instance is None:return selfreturn instance.__dict__.get(self.name, None)def __set__(self, instance, value):if not self.validation_function(value):raise ValueError(f"Invalid value for {self.name}: {value}")instance.__dict__[self.name] = value

现在我们可以创建特定类型的验证描述符:

class PositiveInteger(Validated):def __init__(self):super().__init__(self.validate)@staticmethoddef validate(value):return isinstance(value, int) and value > 0class NonEmptyString(Validated):def __init__(self):super().__init__(self.validate)@staticmethoddef validate(value):return isinstance(value, str) and len(value.strip()) > 0

在类中使用这些描述符:

class Person:age = PositiveInteger()name = NonEmptyString()def __init__(self, name, age):self.name = name  # 调用NonEmptyString的__set__self.age = age    # 调用PositiveInteger的__set__p = Person("Alice", 30)
print(p.age)  # 输出: 30
p.age = -5    # 抛出ValueError: Invalid value for age: -5

高级应用:自动生成文档

__set_name__还可以用于自动生成文档。我们可以创建一个描述符,在类创建时自动为属性添加文档字符串:

class Documented:def __init__(self, docstring=None):self.docstring = docstringself.name = Nonedef __set_name__(self, owner, name):self.name = nameif self.docstring is None:self.docstring = f"属性 {name} 的文档"def __get__(self, instance, owner):if instance is None:return selfreturn instance.__dict__.get(self.name, None)def __set__(self, instance, value):instance.__dict__[self.name] = valueclass Product:price = Documented("产品的价格,必须为正数")quantity = Documented("库存数量,必须为非负整数")def __init__(self, price, quantity):self.price = priceself.quantity = quantity

实际应用场景

  1. ORM框架:在ORM框架中,__set_name__可以用于将Python属性映射到数据库列名
  2. 类型检查:实现运行时类型检查,类似于类型注解但更灵活
  3. 属性代理:创建代理属性,将属性访问重定向到其他对象
  4. 观察者模式:当属性被修改时自动触发事件

注意事项

  1. __set_name__方法只在Python 3.6及以上版本中可用
  2. 描述符应该存储实例值在instance.__dict__中,而不是描述符自身的__dict__
  3. 对于性能敏感的代码,过度使用描述符可能会影响性能
  4. 描述符的优先级高于常规属性、实例方法和类方法

结论

__set_name__是Python描述符协议的一个强大工具,它允许我们在类创建时获取属性名称,从而实现更灵活和强大的属性行为控制。通过使用__set_name__,我们可以创建更加可重用和可维护的代码,特别是在处理复杂属性逻辑时。掌握这一特性将使你的Python代码更加优雅和高效。

正如Effective Python中所强调的,理解描述符和__set_name__的机制是编写高级Python代码的关键一步,它能够帮助你构建更加清晰、可维护的类结构。

http://www.dtcms.com/a/602128.html

相关文章:

  • 泉州市住房与城乡建设网站常用的网站有哪些
  • wordpress站点设置使用期限武夷山网站制作
  • python 迭代器和生成器
  • 编译型语言的两大步骤 | 深入理解编译过程与优化技术
  • (三)分支与合并 - git rebase 命令的使用
  • K8S上高可用SeaTunnel 集群部署
  • wdcp 默认网站中学网站建设方案 分校区
  • 网站营销站点有你想网页设计师个人简历参考范文
  • Windows 使用 docker 搭建 gitea
  • 多维决策系统的工程化实践:从评估框架到智能筛选引擎
  • 二十八、STM32的USART (介绍)
  • 双滦区seo整站排名seo在网站制作
  • 关于网站维护的书籍建设网站的技术性背景
  • 现代CPU性能分析与优化
  • 悬浮提词器免费版哪个好用?功能测评与实用应用场景
  • 使用OpenGL实现Gouraud材质
  • 2025年数据中心不间断电源(UPS)市场报告:趋势、挑战与投资战略全景分析
  • 网站建设开标书哪家公司
  • 【前端面试】CSS篇
  • 第六章,主从服务器
  • 16.udp_socket(三)
  • 【Git Merge branch】Git 合并提交(Merge Commit)的成因与清理:从本地修复到安全重写历史
  • 视觉学习篇——理清机器学习:分类、流程与技术家族的关系
  • 个人 网站备案 幕布wordpress黑群
  • 机器学习日报17
  • 沛县网站建设wordpress 标签 标题
  • 数字孪生IOC:让数据中心运维从“被动响应”到“主动预警”的智能革命
  • 长春作网站建设的公司wordpress上传到服务器发布
  • 炭黑仪:高精度材料分析的关键工具
  • C++条件判断与循环(一)(算法竞赛)