簡體   English   中英

在 Python 中鍵入可變參數 function

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM