我们想要键入一个提示函数

def f(*args:float)->tuple[float,...]:
   ...
   return tuple(args)

使得指定元组中的元素的数目与参数的数目匹配. 当然,这里的返回值是更复杂逻辑的占位符.

我们希望使用mypy或pylance来判断我们是否总是返回a)正确的元素数量和b)所有元素的正确类型.

使用TypeVarTuple(https://peps.python.org/pep-0646/#args-as-a-type-variable-tuple)可以指定我们返回相同数量的元素,但不返回类型.

除了为1个参数、2个参数、3个参数等编写许多重载之外,在当前的python(3.12)中有没有其他方法可以做到这一点?

推荐答案

是的,您可以编写一个no-op修饰符来签名f次拒绝try 传递您不想要的类型.下面的示例使f拒绝任何传递与float不兼容的值的try .

演示: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])
    Ts = t.TypeVarTuple("Ts")
 
    class _FloatOnlyCallable(t.Protocol):
        def __call__(self, /, *args: float) -> t.Any: ...

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

Python相关问答推荐

时间序列分解

连接两个具有不同标题的收件箱

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

ThreadPoolExecutor和单个线程的超时

pandas:排序多级列

导入...从...混乱

在pandas中使用group_by,但有条件

Asyncio:如何从子进程中读取stdout?

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

如何启动下载并在不击中磁盘的情况下呈现响应?

如何更改groupby作用域以找到满足掩码条件的第一个值?

Flash只从html表单中获取一个值

pandas:在操作pandora之后将pandora列转换为int

如何强制向量中的特定元素在Gekko中处于优化解决方案中

Python Mercury离线安装

如何在Django模板中显示串行化器错误

用0填充没有覆盖范围的垃圾箱

使用xlsxWriter在EXCEL中为数据帧的各行上色

普洛特利express 发布的人口普查数据失败

将数据从一个单元格保存到Jupyter笔记本中的下一个单元格