深入理解 Python 描述符机制:以 rainyear/pytips 项目为例
2025-06-10 11:03:00作者:俞予舒Fleming
描述符协议:Python 属性访问的底层机制
在 Python 中,描述符(Descriptor)是一种强大的协议,它允许开发者自定义属性访问的行为。描述符协议定义了三个核心方法:
__get__()
- 控制属性的获取__set__()
- 控制属性的赋值__delete__()
- 控制属性的删除
当我们在 Python 中使用点号(.)访问属性时,实际上是在触发描述符协议。例如,obj.attr
这样的简单属性访问,底层会调用 __getattribute__()
方法,最终可能转化为描述符的 __get__()
方法调用。
描述符的实际应用
1. property 描述符
property 是 Python 中最常用的描述符之一,它允许我们将方法调用伪装成属性访问。在 rainyear/pytips 项目中,展示了 property 的两种使用方式:
方式一:作为函数使用
class Int:
def __init__(self, val):
self._val = val
self._ctype = None
def get_ctype(self):
print("INFO: You can get `ctype`")
return self._ctype
def set_ctype(self, val):
print("INFO: You're setting `ctype` =", val)
self._ctype=val
ctype = property(fget=get_ctype, fset=set_ctype, doc="Property `ctype`")
方式二:作为装饰器使用(更简洁)
class Int:
_ctype = None
def __init__(self, val):
self._val = val
@property
def ctype(self):
print("INFO: You can get `ctype` from me!")
return self._ctype
@ctype.setter
def ctype(self, val):
print("INFO: You're setting `ctype` =", val)
self._ctype = val
property 描述符的主要优势在于:
- 可以在属性访问时执行额外的逻辑
- 保持接口一致性(方法调用看起来像属性访问)
- 实现属性的只读、只写或读写控制
2. staticmethod 和 classmethod 描述符
这两个描述符用于控制方法的调用方式:
staticmethod - 将方法转换为静态方法,不接收隐式的第一个参数(self 或 cls)
class Int:
@staticmethod
def get_ctype():
print("INFO: You can get `ctype` from here!")
return "Class::StaticInt"
classmethod - 将方法转换为类方法,接收类作为隐式的第一个参数(通常命名为 cls)
class Int:
_ctype = ""
@classmethod
def set_ctype(klass, t):
klass._ctype = t
return "{}.ctype = {}".format(klass.__name__, t)
关键区别:
- 静态方法:与类和实例都无关,相当于普通函数
- 类方法:可以访问和修改类状态,但不能访问实例状态
描述符的实现原理
在 rainyear/pytips 项目中,还展示了如何用纯 Python 实现这些内置描述符。理解这些实现有助于深入掌握描述符的工作原理:
Property 实现
class Property(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc or fget.__doc__
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)
# 其他方法省略...
StaticMethod 实现
class StaticMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, objtype=None):
return self.f
ClassMethod 实现
class ClassMethod(object):
def __init__(self, f):
self.f = f
def __get__(self, obj, klass=None):
if klass is None:
klass = type(obj)
def newfunc(*args):
return self.f(klass, *args)
return newfunc
实际开发中的应用场景
- 数据验证:在属性赋值时检查数据有效性
- 延迟计算:只在首次访问时计算属性值
- 访问控制:实现只读属性或权限检查
- API 设计:提供更优雅的接口
- ORM 框架:实现对象-关系映射
总结
Python 的描述符机制是许多高级特性的基础,理解它可以帮助我们:
- 更深入地理解 Python 的对象模型
- 编写更灵活、更强大的类
- 更好地使用内置的 property、staticmethod 和 classmethod
- 理解框架(如 Django、SQLAlchemy)的工作原理
通过 rainyear/pytips 项目中的示例,我们可以清晰地看到描述符如何将简单的属性访问转化为方法调用,从而实现对属性访问过程的完全控制。掌握描述符是成为 Python 高级开发者的重要一步。
登录后查看全文
热门项目推荐
PaddleOCR-VL
PaddleOCR-VL 是一款顶尖且资源高效的文档解析专用模型。其核心组件为 PaddleOCR-VL-0.9B,这是一款精简却功能强大的视觉语言模型(VLM)。该模型融合了 NaViT 风格的动态分辨率视觉编码器与 ERNIE-4.5-0.3B 语言模型,可实现精准的元素识别。Python00- DDeepSeek-V3.2-ExpDeepSeek-V3.2-Exp是DeepSeek推出的实验性模型,基于V3.1-Terminus架构,创新引入DeepSeek Sparse Attention稀疏注意力机制,在保持模型输出质量的同时,大幅提升长文本场景下的训练与推理效率。该模型在MMLU-Pro、GPQA-Diamond等多领域公开基准测试中表现与V3.1-Terminus相当,支持HuggingFace、SGLang、vLLM等多种本地运行方式,开源内核设计便于研究,采用MIT许可证。【此简介由AI生成】Python00
openPangu-Ultra-MoE-718B-V1.1
昇腾原生的开源盘古 Ultra-MoE-718B-V1.1 语言模型Python00ops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。C++0124AI内容魔方
AI内容专区,汇集全球AI开源项目,集结模块、可组合的内容,致力于分享、交流。02Spark-Chemistry-X1-13B
科大讯飞星火化学-X1-13B (iFLYTEK Spark Chemistry-X1-13B) 是一款专为化学领域优化的大语言模型。它由星火-X1 (Spark-X1) 基础模型微调而来,在化学知识问答、分子性质预测、化学名称转换和科学推理方面展现出强大的能力,同时保持了强大的通用语言理解与生成能力。Python00GOT-OCR-2.0-hf
阶跃星辰StepFun推出的GOT-OCR-2.0-hf是一款强大的多语言OCR开源模型,支持从普通文档到复杂场景的文字识别。它能精准处理表格、图表、数学公式、几何图形甚至乐谱等特殊内容,输出结果可通过第三方工具渲染成多种格式。模型支持1024×1024高分辨率输入,具备多页批量处理、动态分块识别和交互式区域选择等创新功能,用户可通过坐标或颜色指定识别区域。基于Apache 2.0协议开源,提供Hugging Face演示和完整代码,适用于学术研究到工业应用的广泛场景,为OCR领域带来突破性解决方案。00- HHowToCook程序员在家做饭方法指南。Programmer's guide about how to cook at home (Chinese only).Dockerfile011
- PpathwayPathway is an open framework for high-throughput and low-latency real-time data processing.Python00
项目优选
收起

deepin linux kernel
C
23
6

OpenHarmony documentation | OpenHarmony开发者文档
Dockerfile
229
2.28 K

仓颉编译器源码及 cjdb 调试工具。
C++
112
72

暂无简介
Dart
527
116

仓颉编程语言运行时与标准库。
Cangjie
122
91

React Native鸿蒙化仓库
JavaScript
215
289

Ascend Extension for PyTorch
Python
70
101

🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
990
586

本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
567
102

旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
1.02 K
400