Python 类型提示 可使用一种已知位置类型调用,然后使用 *args 和 **kwargs

Int*_*rer 4 python typing type-hinting mypy

我的以下功能foo,其中有:

  • 具有已知类型的一个位置 arg
  • 之后有可变数量的位置参数和关键字参数
from typing import Callable

def foo(bar: str, *args, **kwargs) -> None:
    """Some function with one positional arg and then *args and **kwargs."""

foo_: Callable[[str, ...], None] = foo  # error: Unexpected '...'
Run Code Online (Sandbox Code Playgroud)

我如何输入提示?

目前,mypy==0.812抛出错误:error: Unexpected '...' [misc]

Mar*_*hac 5

您现在不能像 Samwise 的评论所说的那样执行此操作,但在 Python 3.10 中(在PEP 612:参数规范变量下),您将能够执行此操作:

from typing import Callable, ParamSpec, Concatenate

P = ParamSpec("P")

def receive_foo(foo: Callable[Concatenate[str, P], None]):
    pass
Run Code Online (Sandbox Code Playgroud)

我不确定您是否能够为其声明 a TypeAlias(因为不能在全局范围内使用),因此您可能必须每次都P指定内联类型。P


Jos*_*iah 5

我可能会为此使用协议。它们通常比 Callables 更灵活一些。它看起来像这样

from typing import Protocol

class BarFunc(Protocol):
    def __call__(fakeself, bar: str, *args, **kwargs) -> None:
        # fakeself gets swallowed by the class method binding logic
        # so this will match functions that have bar and the free arguments.
        ...

def foo(bar: str, *args, **kwargs) -> None:
    """Some function with one positional arg and then *args and **kwargs."""

foo_: BarFunc = foo
Run Code Online (Sandbox Code Playgroud)