from typing import Callable, TypeVar
T = TypeVar('T')
IndicatorFunction = Callable[[T], bool]
# mypy accepts this annotation.
s1: Callable[[T], bool] = lambda x: False
# mypy rejects this annotation, but it's just an alias of the first one.
s2: IndicatorFunction[T] = lambda x: False
我試圖了解如何讓 mypy 考慮T系結在s2上述代碼片段的型別注釋中。我收到以下錯誤:
main.py:9: error: Type variable "__main__.T" is unbound
main.py:9: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
main.py:9: note: (Hint: Use "T" in function signature to bind "T" inside a function)
Found 1 error in 1 file (checked 1 source file)
這些提示有助于告訴我如何在類和函式簽名中系結“T”,但不告訴我如何為 lambda 運算式的型別注釋系結。
子問題:
- 如何在 的型別注釋中系結 T
s2? - 為什么我在 的型別注釋中沒有得到相同的錯誤
s1?由于IndicatorFunction是s1's 型別的別名,我希望s1和s2都被mypy.
uj5u.com熱心網友回復:
在閱讀了很多 PEP 和mypy問題跟蹤器之后,我相信我明白這里發生了什么。
如何
T在 的型別注釋中系結s2?
你不能。PEP 526中沒有為它定義語法,它引入了變數注釋。
據我所知,正如 mypy 的錯誤訊息所暗示的那樣,目前只有兩種方法可以T在 Python 中量化(系結)型別變數:
- 在類定義中,通過在繼承串列(或從這兩個繼承的另一個類)中包含一個
Generic[T]或。Protocol[T]換句話說,Generic和Protocol是“神奇的”隱式型別變數系結器。 - 在函式定義的引數串列中,通過使用包含
T作為型別引數的泛型型別來注釋引數。
無法在PEP 526變數注釋中引入型別變數系結。PEP 526 幾乎沒有提到型別引數和泛型。
Python 將來會在變數注解中添加系結型別變數的方法嗎?看起來不像。PEP 695如果被接受,將極大地提高型別變數系結語法的清晰度,但同樣,它只處理上述兩種情況:在類或函式定義中引入系結,而不是在變數注釋中。
所有這一切所暗示的下一個問題是為什么 mypy 將s1其視為有效且隱式系結T?T如果您嘗試給它以下代碼,您可以看到 mypy 確實隱式系結:
T = TypeVar('T')
s3: Callable[[T], bool] = lambda x: x False
mypy給出這些錯誤:
main.py:5: error: Incompatible types in assignment (expression has type "Callable[[T], int]", variable has type "Callable[[T], bool]")
main.py:5: error: Unsupported operand types for ("T" and "bool")
main.py:5: error: Incompatible return value type (got "int", expected "bool")
第二個,Unsupported operand types for ("T" and "bool"),表明mypy確實系結T并推斷出x型別為T。
這似乎是一個mypy 錯誤。事實上,關于該錯誤的第一批評論之一是Callable關于Callable被mypy.
這就回答了第二個問題:
為什么我在 的型別注釋中沒有得到相同的錯誤
s1?由于IndicatorFunction是s1's 型別的別名,我希望s1和s2都被mypy.
就是上面那個mypybug。
相比之下,Pyright 正確地拒絕了s1,并抱怨Type variable "T" has no meaning in this context- 換句話說,T是不受約束的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/511351.html
上一篇:如何通過泛型更改結構標簽
