[英]Python Typing: declare return value type based on function argument
假設我有將類型作為參數並返回該類型實例的函數:
def fun(t):
return t(42)
然后我可以調用它並獲取所提供類型的對象:
fun(int) # 42
fun(float) # 42.0
fun(complex) # (42+0j)
fun(str) # "42"
fun(MyCustomType) # something
該列表並不詳盡,我希望能夠使用具有適當構造函數的任何類型。
然后,我想為該函數添加類型提示。 該函數的返回值的類型提示應該是什么?
我試過簡單地使用t
,因為t
是一種類型:
def fun(t: type) -> t:
return t(42)
但這不起作用:
main.py:1: 錯誤:未定義名稱“t”
from typing import TypeVar
T = TypeVar("T")
def fun(t: T) -> T:
return t(42)
但這似乎不對,因為T
表示一種類型,所以它表明返回的是類型本身,而不是它的實例。 Mypy 拒絕它:
main.py:6: 錯誤:“對象”不可調用
使用Any
顯然有效,但我覺得它太模糊了,它沒有傳達意圖:
from typing import Any
def fun(t: type) -> Any:
return t(42)
您正在尋找typing.Type
,因此具有以下效果:
from typing import TypeVar, Type
T = TypeVar("T", str, complex, float, int)
def fun(t: Type[T]) -> T:
return t(42)
fun(int)
fun(float)
fun(complex)
fun(str)
請注意,您的類型變量需要受到約束,因為並非所有Type
對象都接受參數,但您可以將其限制為一些與您的示例類似的變量。
TLDR:您需要一個TypeVar
作為調用t
的返回類型:
def fun(t: Callable[[int], R]) -> R:
...
這里對類型的約束過於嚴格。 該函數接受任何采用整數的Callable
,並且該函數的返回類型是Callable
。 這可以使用返回類型的TypeVar
指定:
from typing import Callable, TypeVar
R = TypeVar('R') # the variable return type
def fun(t: Callable[[int], R]) -> R:
return t(42)
fun(int) # Revealed type is 'builtins.int*'
fun(float) # Revealed type is 'builtins.float*'
reveal_type(fun(lambda x: str(x))) # Revealed type is 'builtins.str*'
這也適用於類型,因為類型實例化是一個調用。
如果需要更復雜的簽名,例如帶有關鍵字參數,請使用Protocol
(來自typing
或typing
typing_extensions
)。
請注意,如果明確只想將42
傳遞給Callable
,則可以使用Literal
(來自typing
或typing_extensions
)來指定這一點。
R = TypeVar('R')
def fun(t: Callable[[Literal[42]], R]) -> R:
return t(42)
請注意,任何Callable[[int], R]
類型的函數也滿足Callable[[Literal[42]], R]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.