Typehint 函数 *args -> tuple[*args] 对 args 进行约束

问题描述 投票:0回答:1

我们想要输入提示函数

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) 是否有方法可以做到这一点?

python mypy python-typing pylance
1个回答
0
投票

是的,您可以编写一个无操作装饰器来制作

f
的签名,以拒绝传递您不想要的类型的尝试。以下示例使
f
拒绝任何传递与
float
不兼容的值的尝试。

演示:mypy PlaygroundPyright 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
© www.soinside.com 2019 - 2024. All rights reserved.