我们想要输入提示函数
def f(*args:float)->tuple[float,...]:
...
return tuple(args)
指定元组中的元素数量与参数数量匹配。 当然,这里的 return 是一个占位符,用于更复杂的逻辑。
我们想使用 mypy 或 pylance 来检查我们是否总是返回 a) 正确的元素数量和 b) 所有元素的正确类型。
使用
TypeVarTuple
(https://peps.python.org/pep-0646/#args-as-a-type-variable-tuple)将允许指定我们返回相同数量的元素,但不是类型。
除了为 1 参数、2 参数、3 参数等编写许多重载之外,当前的 python (3.12) 是否有方法可以做到这一点?
是的,您可以编写一个无操作装饰器来制作
f
的签名,以拒绝传递您不想要的类型的尝试。以下示例使 f
拒绝任何传递与 float
不兼容的值的尝试。
演示:mypy Playground、Pyright Playground
import typing_extensions as t
if t.TYPE_CHECKING:
import collections.abc as cx
F = t.TypeVar("F", bound=cx.Callable[..., t.Any])
R = t.TypeVar("R", covariant=True)
Ts = t.TypeVarTuple("Ts")
class _FloatOnlyCallable(t.Protocol[R]):
def __call__(self, /, *args: float) -> R: ...
def asFloatOnlyCallable(f: F, /) -> F | _FloatOnlyCallable:
"""Decorate a function to make it only accept variadic positional float arguments"""
return f
@asFloatOnlyCallable
def f(*args: *Ts) -> tuple[*Ts]:
return args
>>> a, b = f(1.0, 2.0) # OK
>>> c, d = f("3.0", 4.0) # Error: Incompatible type "str", expected "float"
>>> e, g, h = f(5.0, 6.0) # Error: Need more values to unpack