【Python】一些PEP提案(五):注解的延迟求值

类型注解从诞生开始就保持一个基本的原则,也就是加与不加不应该影响Python代码的运行,但是很多提案都在给这个机制擦屁股。

PEP 563:字符串化(Postponed Evaluation of Annotations)

我们看一个例子:

python 复制代码
# ❌ 报错:NameError
class TreeNode:
    def __init__(self, left: TreeNode):  # 定义时 TreeNode 还没创建完成
        pass

如果是上面这种情况,其实一般的解决办法就是直接去掉类型注解了。但如果我就是不想去掉,那就得想点其他办法了。

PEP 563 的做法就是,把注解变成字符串存起来:

python 复制代码
from __future__ import annotations

def func(x: int, y: list[str]):
    pass

print(func.__annotations__)
# 输出:{'x': 'int', 'y': 'list[str]'}  ← 全是字符串!

编译器在编译代码时,直接将注解表达式转换为字符串字面量,存储在 __annotations__ 字典中。字符串不需要名字存在,自然解决了 TreeNode 问题。

但是,许多库(Pydantic, FastAPI, SQLAlchemy)依赖 __annotations__ 获取真实的类型对象来做验证或 ORM 映射,现在只能拿到字符串了。这意味着需要专门为这个PEP做适配。

PEP 649:描述符延迟求值(Deferred Evaluation Using Descriptors)

Python 3.13+ 默认启用,是 PEP 563 的继任者和替代者。

PEP 649 不存储字符串,而是存储编译后的代码对象(Code Objects)。

它引入了一个新的 __annotations__ 映射对象,这个对象是一个描述符(Descriptor)。当你访问注解时,它会自动执行存储的代码块,求值得到真实的类型对象,并缓存结果。

python 复制代码
# Python 3.13+ (默认行为,无需 import)
def func(x: int, y: list[str]):
    pass

print(func.__annotations__)
# 输出:{'x': <class 'int'>, 'y': list[str]}  ← 看起来是真实对象!
# 实际上底层是延迟求值的,但对外表现透明

(我手头并没有python3.13的环境,所以无法保证上述运行结果是正确的)

其实上述代码在早期Python版本也能正常运行,开启3.13的PEP649后,应该能确保两件事:

  1. 不再出现前向声明导致崩溃的问题
  2. 如果执行如下代码,应该会输出对应的结果:
python 复制代码
# Python 3.13+
def func(x: int): pass

print(type(func.__annotations__)) 
# 3.12 及之前:<class 'dict'>
# 3.13+: <class 'annotations'> (或类似的代理对象)
相关推荐
江屿风2 分钟前
【C++笔记】List流食般投喂
开发语言·c++·笔记·list
hhzz5 分钟前
CNN猫狗图像分类实战:基于Keras+TensorFlow的卷积神经网络全流程解析
图像处理·python·深度学习·计算机视觉·cnn
辞旧 lekkk10 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
帅次10 小时前
Kotlin 与 Java 互操作:混合工程里的平台类型与 API 边界
java·开发语言·kotlin·suspend·nullable
dtq042412 小时前
C语言-结构体详解
c语言·开发语言·学习
梅雅达编程笔记12 小时前
编程启蒙|Scratch 转 Python 系列第9天:字典/哈希表积木双向对照(AI大模型参数配置表实战)
开发语言·人工智能·python·numpy·pandas
持力行12 小时前
C++与Java变量声明、定义及内存分配的核心区别
java·开发语言·c++
zhz521413 小时前
GIS项目中空间参考转换与MBTiles偏移:问题成因、解法与避坑
python·vue·gis
jinyishu_13 小时前
C++ 继承全解:从基础到高级特性
开发语言·c++
KaMeidebaby14 小时前
卡梅德生物技术快报|如何制备单克隆抗体:小众禽类靶点单抗制备实操流程:双载体抗原交叉筛选完整工艺记录
人工智能·python·深度学习·算法·机器学习