我目前正在创建一个 Python 线性代数模块,以供娱乐和练习该语言。我最近尝试向模块添加类型注释,如下所示:
class Vector:
# Various irrelevant implementation details
def __add__(self, other: Vector) -> Vector:
# More implementation details....
但是,当我尝试导入它时,它会吐出一个
NameError: Name 'Vector' is not defined
。我承认这个问题已经以here的形式得到了回答,但它似乎并没有完全为我的情况提供答案。
我想知道的是:
Vector
使其可用于注释(作为 type
)?您有前瞻性声明;函数(作为方法绑定)是在类创建之前创建的,因此名称 Vector
尚不存在。只有当所有类体都被执行后,Python 才能创建
class
对象并将名称 Vector
绑定到它。只需使用带有名称的字符串即可:
class Vector:
# Various irrelevant implementation details
def __add__(self, other: 'Vector') -> 'Vector':
# More implementation details....
这不会影响您的 IDE 如何查看声明;加载整个模块后就会查找字符串,并将其解析为当前上下文中的有效 Python 表达式。由于类
Vector
在整个模块加载后就存在,因此字符串
'Vector'
可以正确地转换为类对象。另请参阅有关前向引用的规范当类型提示包含尚未定义的名称时,该定义可能会表示为字符串文字,稍后再解析。[...]
字符串文字应包含有效的 Python 表达式 [...],并且一旦模块完全加载,它的计算结果应该不会出现错误。
从 Python 3.7 开始,您可以通过在模块顶部添加
from __future__ import annotations
指令,使给定模块中的所有注释都表现得像前向注释(无需将它们包含在字符串文字中)。最初计划将此设置为 Python 3.10 及更高版本中的默认设置,但此决定现已无限期推迟。有关详细信息,请参阅
PEP 563 --推迟的注释评估。请注意,注释的outside您可能仍然需要使用前向引用语法(字符串文字),例如在类型别名中(就 Python 而言,这是常规变量赋值)。