使用类型 stub ,我想知道是否可以在 Python 中表达一种类型,允许您为任意数量的参数正确键入:
def test(*args):
return args
乍一看,我有:
T = TypeVar('T')
def test(*args: T) -> Tuple[T, ...]:
return args
但这当然只会正确输入第一个 T。
是否是为所有参数编写覆盖的唯一可能方法?
T1 = TypeVar('T1')
T2 = TypeVar('T2')
T3 = TypeVar('T3')
T4 = TypeVar('T4')
@overload
def test(arg1: T1) -> Tuple[T1]: ...
@overload
def test(arg1: T1, arg2: T2) -> Tuple[T1, T2]: ...
@overload
def test(arg1: T1, arg2: T2, arg3: T3) -> Tuple[T1, T2, T3]: ...
@overload
def test(arg1: T1, arg2: T2, arg3: T3, arg4: T4) -> Tuple[T1, T2, T3, T4]: ...
# etc
def test(*args: Any) -> Tuple[Any, ...]:
return args
这也不完整,因为它没有携带足够的类型信息来键入如下内容:
x: Tuple[int, int, str] = test(*[1, 2, "4"])
最佳答案
这可以通过来自PEP646 的TypeVarTuple
来解决,在 Python 3.11 或前向兼容模块中实现 typing-extensions .
请看这个模拟示例:
from __future__ import annotations
from typing import Any, Callable, Generic
from typing_extensions import TypeVarTuple, Unpack # typing_extensions only needed for Python < 3.11
Ts = TypeVarTuple("Ts")
class Signal(Generic[Unpack[Ts]]):
def add_callback(self, func: Callable[[Unpack[Ts]], Any]) -> None:
...
def emit(self, *args: Unpack[Ts]) -> None:
...
def callback(a: int, b: str) -> None:
...
def callback_bad(a: str) -> None:
...
sig: Signal[int, str] = Signal()
sig.add_callback(callback) # Good lint
sig.add_callback(callback_bad) # Bad lint
sig.emit(1223, "foo") # Good lint
sig.emit("bar") # Bad lint
另见 Dynamic TypeVar for a sequence of types寻求解决方案。
关于python - *(解包)运算符可以在 Python 中输入吗?或者任何其他可变参数函数使得所有可变类型都在结果类型中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67920245/