描述器实现 property
描述器实战应用
引言
在 Python 官方文档中的 描述器使用指南 一篇中,给出了常用装饰器 property 的 Python 代码模拟实现,且这个实现是基于描述器原理的。在本文中,作者将利用这段代码,向你展示 描述器的实际运行原理。
装饰器基本内容
首先我们回忆一下装饰器的有关内容。
装饰器本质是个返回函数的函数,表现为数学概念中的复合函数
下面我们用伪代码再补充一些容易产生疑问的情况。
多层装饰器的含义
@dec2
@dec1
def func(arg1, arg2, ...):
pass↑↑↑ 等价于 ↓↓↓
func = dec2(dec1(func))带参装饰器的含义
@decomaker(argA, argB, ...)
def func(arg1, arg2, ...):
pass↑↑↑ 等价于 ↓↓↓
类装饰器和函数装饰器是一致的,只相当于将 func 代表的函数换做 cls 代表的类罢了,故这里不再多做涉及。
如果对于装饰器还有问题的话建议阅读一下官方 PEP,可以直接使用 Google 翻译成中文,可读性还是可以接受的。
PEP 318 -- Decorators for Functions and Methods PEP 3129 – Class Decorators
描述器基本内容
这里推荐我针对描述器撰写的上一篇博文
官方模拟的源码
我们首先看一下用描述器模拟实现装饰器 property 的源代码。
(这里大概看一下就好,我们后文再详细分析)
代码分析
改写测试用代码
其实作者比较喜欢的方式是利用 VS Code 在代码段顶部就加上断点,然后逐句执行查看代码的具体运行位置和变量值。
但这种方式难以通过文字向大家展示,所以我换了个变通的方式,在每个关键环节都加一个 print() 输出相关内容,这样我们看代码的命令行反馈就可以了。
更改后的测试代码如下:
全部输出
运行以上代码得到的输出是:
由于这其中涉及的内容较多,我们拆开来做分析。
初始化部分
对象 a1 创建及属性操作部分
对象 a2 创建及属性操作部分
@property 中的小陷阱
@property 装饰后生成的描述器实际上成为了数据描述器!
扩展内容
其实在同一篇中官方也给出了 staticmethod 和 classmethod 的类似模拟实现,有兴趣的读者也不妨一览:
参考
最后更新于