3 回答
TA貢獻1824條經驗 獲得超6個贊
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貢獻1777條經驗 獲得超10個贊
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)添加回答
舉報
