首页 > 解决方案 > Python 类型检查器会尊重 __annotations__ 动态设置吗?

问题描述

所以我正在阅读PEP 563 - Postponed Evaluation of Annotations,它说:

在 Python 3.10 中,函数和变量注释将不再在定义时进行评估。相反,字符串形式将保留在相应的__annotations__字典中。静态类型检查器在行为上没有区别,而在运行时使用注释的工具将不得不执行延迟评估。

这让我想知道,如果类型检查器实现了这个 PEP 的建议,这是否意味着

def f(foo: str):
    pass

是否相当于这种形式?

def f(foo):
    pass

f.__annotations__ = {"foo": "str"}

我测试了 mypy、PyCharm 和 pytype,都不尊重动态添加的__annotations__. 所以我的问题是:

我的理解是否正确,类型检查器最终会支持它,还是我误解了 PEP?

标签: pythontype-hintingpython-typing

解决方案


PEP 563 是关于注释的延迟评估。这与注释是否存储在__annotations__属性内无关。注释已经并将被存储在 中__annotations__,只有它们存储的格式会发生变化。

这句话

静态类型检查器将看不到行为差异

实际上与您的想法相反:类型检查器从未检查过__annotations__属性,因此不会看到任何差异。


考虑带注释的函数ff.__annotations__因此:

def f(foo: str): ...

print(f.__annotations__)

在 Python 3.9 或更早版本中,这会打印:

{'foo': <class 'str'>}

使用from __future__ import annotations启用 PEP 563,这将打印:

{'foo': 'str'} 

换句话说,__annotations__值的类型发生了变化,但注解本身没有任何区别。由于类型检查器检查的是实际的注释,而不是__annotations__属性,因此它们“也不会看到行为上的差异”。


推荐阅读