![](/img/trans.png)
[英]Python TypeHint a function that returns different types based on input
[英]Typehint a variadic function in Python
我寫了一個高階 python function(我們稱它為parent
),它的參數 function(我們稱它為child
)是一個可變參數 function。
我不知道如何輸入提示。
child
將始終是str
的第一個參數和可變數量的參數作為參數,參數可以是任何東西。 它返回Any
。
我能得到的最接近它的是Callable[..., Any]
但后來我“失去”了第一個參數是str
的事實。
我想要Callable[[str,...], Any]
之類的東西,但這不是有效的類型提示。
有沒有辦法打字提示我的 function?
使用 協議不需要您手動將值包裝在“類型提示包裝器”中,但不幸的是它在這里對您沒有幫助。
如果一個 function 可以匹配一個協議,它的簽名必須與協議中的__call__
方法的簽名完全匹配。 但是,(如果我沒記錯的話)您想將任何 function 與一個字符串作為第一個參數匹配,它可以是以下任何一個:
def fn1(x: str) -> Any: ...
def fn2(x: str, arg1: int, arg2: float) -> Any: ...
def fn3(x: str, *args: Any, **kwargs: Any) -> Any: ...
這些都有不同的簽名,因此無法通過單一協議匹配:( mypy-play )
from typing import Any, Protocol
# This might be the protocol you might use, but unfortunately it doesn't work.
class StrCallable(Protocol):
def __call__(self, x: str, *args, **kwargs) -> Any:
...
def my_higher_order_fn(fn: StrCallable) -> StrCallable:
return fn # fill this with your actual implementation
my_higher_order_fn(fn1) # fails
my_higher_order_fn(fn2) # fails
my_higher_order_fn(fn3) # this passes, though
PEP 612引入了ParamSpec
,這是您在這里需要的。 它有點像TypeVar
,但用於 function 簽名。 您可以在Callable
中放置第一個列表參數的地方放置一個ParamSpec
:
from typing import Callable, Concatenate, ParamSpec, TypeVar
P = ParamSpec("P")
TRet = TypeVar("TRet")
StrCallable = Callable[Concatenate[str, P], TRet]
其中Concatenate
將類型連接到現有參數規范。 Concatenate[str, P]
正是您所需要的:第一個參數為str
的任何 function 簽名。
不幸的是,PEP 612 直到 Python 3.10 才可用,mypy 也還沒有完全支持它。 在那之前,您可能只需要使用Callable[..., TRet]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.