我想注释一个泛型函数,它将另一个函数及其参数作为参数.

def forward(func, **kwargs):
    func(**kwargs)

所以,如果我有一个函数,它接受两个整数:

def sum_int(a: int, b: int):
    ...

在我的编辑器中,如果我传递了错误的对象类型,我需要帮助:

forward(sum_int, 1.5, 2.6)   # want type checker to complain about using floats instead of integers

我怎么才能给forward加注释呢?类似于:

def forward(func: Callable[rest, ret], **kwargs: rest] -> ret:
    ...

因此,forward的第一个参数是func,而rest是关键字参数.回报是ret美元.但是restret也是func的关键字参数和返回类型.

几年前(几十年前!)我用C++做泛型,有捕获和解包各种类型的技巧,但我不知道我们是否必须用Python跳过这些圈子,或者这是否可能.

我真的不知道要搜索什么,也没有找到任何几乎有帮助的东西.

谢谢!

推荐答案

你可以使用typing.ParamSpec来将func所期望的参数与forward所期望的参数相关联,尽管你显然需要在forward的定义中同时使用位置参数和关键字参数:

RV = TypeVar('RV')
P = ParamSpec('P')


def forward(func: Callable[P, RV], *args: P.args, **kwargs: P.kwargs) -> RV:
    ...


def foo(*, a: int, b: int) -> str:
    ...

forward(foo, a=3, b=5)  # OK
forward(foo, 3, 5)  # Not OK, too many positional arguments for foo

Python相关问答推荐

在IIS中运行的FastAPI-获取权限错误:[Win错误10013]试图以其访问权限禁止的方式访问插槽

如何将Pydantic URL验证限制为特定主机或网站

有什么方法可以修复奇怪的y轴Python matplotlib图吗?

Python中的Pool.starmap异常处理

如何从格式为note:{neighbor:weight}的字典中构建networkx图?

使用imap-tools时错误,其邮箱地址包含域名中的非默认字符

Polars:使用列值引用when / then表达中的其他列

在应用循环中间保存pandas DataFrame

如何在Python中使用时区夏令时获取任何给定本地时间的纪元值?

使用scipy. optimate.least_squares()用可变数量的参数匹配两条曲线

如何根据日期和时间将状态更新为已过期或活动?

点到面的Y距离

在Python Attrs包中,如何在field_Transformer函数中添加字段?

' osmnx.shortest_track '返回有效源 node 和目标 node 的'无'

切片包括面具的第一个实例在内的眼镜的最佳方法是什么?

如何从.cgi网站刮一张表到rame?

如何在Python脚本中附加一个Google tab(已经打开)

在单个对象中解析多个Python数据帧

如何在PySide/Qt QColumbnView中删除列

Polars将相同的自定义函数应用于组中的多个列,