3 回答
TA贡献1845条经验 获得超8个赞
from __future__ import annotations
NameError: name 'Position' is not defined
Position
Python 3.7+: from __future__ import annotations
from __future__ import annotations
from __future__ import annotationsclass Position: def __add__(self, other: Position) -> Position: ...
import typing
Python<3.7:使用字符串
根据PEP 484
class Position: ... def __add__(self, other: 'Position') -> 'Position': ...
self
来源
正向参考
当类型提示包含尚未定义的名称时,该定义可以表示为字符串文本,待稍后解析。
这种情况通常发生在容器类的定义上,其中定义的类发生在某些方法的签名中。例如,以下代码(简单二叉树实现的开始)无法工作:
class Tree: def __init__(self, left: Tree, right: Tree): self.left = left self.right = right
为了解决这一问题,我们写道:
class Tree: def __init__(self, left: 'Tree', right: 'Tree'): self.left = left self.right = right
字符串文字应该包含一个有效的Python表达式(即编译(LIT,‘val’)应该是一个有效的代码对象),并且一旦模块被完全加载,它应该在没有错误的情况下进行计算。计算它的本地和全局命名空间应该是相同的名称空间,其中将计算相同函数的默认参数。
在Python4.0中,函数和变量注释将不再在定义时计算。相反,字符串窗体将保留在相应的 __annotations__
字典。静态类型检查器在行为上没有区别,而在运行时使用注释的工具将不得不执行延迟的评估。 ...
可以使用以下特殊导入从Python3.7开始启用上面描述的功能:
from __future__ import annotations
你可能会被诱惑去做的事情
A.定义假人 Position
class Position(object): passclass Position(object): ...
NameError
>>> Position.__add__.__annotations__{'other': __main__.Position, 'return': __main__.Position}
>>> for k, v in Position.__add__.__annotations__.items():... print(k, 'is Position:', v is Position) return is Position: Falseother is Position: False
B.为添加注释而进行的猴子补丁程序:
class Position: ... def __add__(self, other): return self.__class__(self.x + other.x, self.y + other.y)
Position.__add__.__annotations__['return'] = PositionPosition.__add__.__annotations__['other'] = Position
>>> for k, v in Position.__add__.__annotations__.items():... print(k, 'is Position:', v is Position) return is Position: Trueother is Position: True
结语
from __future__ import annotations
TA贡献1804条经验 获得超8个赞
def __add__(self, other: 'Position') -> 'Position': return Position(self.x + other.x, self.y + other.y)
from typing import TypeVarT = TypeVar('T', bound='Position')class Position: def __init__(self, x: int, y: int): self.x = x self.y = y def __add__(self, other: T) -> T: return Position(self.x + other.x, self.y + other.y)
添加回答
举报