从 __future__ 导入注释
- 2025-03-19 08:56:00
- admin 原创
- 6
问题描述:
Python 文档__future__
在 Python 文档中__future__
有一个表格,其中显示注释在 3.7.0b1 中是“可选的”,在 4.0 中是“强制的”,但我仍然可以在 3.8.2 中使用注释而无需导入注释。既然如此,它有什么用呢?
>>> def add_int(a:int, b:int) -> int:
... return a + b
>>> add_int.__annotations__
{'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
我怀疑我是否清楚地理解了这里“可选”和“强制”的含义
解决方案 1:
强制性是一个有趣的词语选择。我猜这意味着它是语言中的默认选项。你不必使用from __future__ import annotations
该annotations
功能参考了 PEP 563:推迟对注释的评估。这是对现有注释功能的增强,该功能最初在 Python 3.0 中引入,并在 Python 3.5 中重新定义为类型提示,这就是您的代码在 Python 3.8 下运行的原因。
from __future__ import annotations
以下是Python 3.7+ 中的可选更改:
class A:
def f(self) -> A: # NameError: name 'A' is not defined
pass
但这有效
from __future__ import annotations
class A:
def f(self) -> A:
pass
请参阅python 3.7 中有关推迟注释的新功能的章节:
由于此更改破坏了兼容性,因此需要在 Python 3.7 中使用导入功能在每个模块中启用新行为
__future__
:
from __future__ import annotations
它将成为 Python 3.10中的默认设置*。
它在 3.10 版(python3.7 发布时)被宣布为默认版本,但现在已移至更高版本
解决方案 2:
强制,即默认出现。可选,即需要从from __future__ import annotations
语句中“激活”
解决方案 3:
第一部分很简单:你可以使用注释,因为注释自 Python 3.0 以来就已经存在,你不需要导入任何东西就__future__
可以使用它们
如果你这样做,你导入的from __future__ import annotations
是延迟注释。延迟注释功能意味着你可以在注释中使用某些内容,即使它尚未定义
请尝试以下操作:
def get_a_pineapple() -> Pineapple:
fresh_pineapple = Pineapple()
return fresh_pineapple
class Pineapple:
pass
print("....whatever you want to print")
如果你尝试运行该脚本,你会得到NameError: name 'Pineapple' is not defined
有三件简单的事情可以让你摆脱 NameError:
删除
-> Pineapple
类型提示。这是可行的,这表明注释/类型提示是问题的一部分将类定义向上移动,使其位于函数定义之前。这也有效,这表明顺序有所不同
将提示替换
-> Pineapple
为-> "Pineapple"
。(这个与问题不太相关,但它是适用于大多数类型检查工具的有效选项)导入
__future__.annotations
。这也有效,因为它改变了规则,顺序不再有区别
数字 (2) 可能是最有趣的,因为它展示了 Python 3 的正常规则:如果你使用名称作为类型提示,那么该名称必须在类型提示之前已经定义。数字 (4) 显示了导入的目的__future__.annotations
:它改变了该规则
(至于‘4.0 中的强制性’,我认为它的意思是推迟注释将成为 Python 4.0 解释器的强制性功能。即如果有人正在编写 Python 4.0 解释器,那么必须赋予它此功能)