python - ParamSpec 可以用来输入单个参数吗?

标签 python python-3.x function decorator

我正在尝试输入以下包装器函数。它需要另一个函数和该函数的参数并运行它,但会产生一些副作用。

from typing import Callable, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")


def wrapper(func: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
    # Run some side effects
    return func(*args, **kwargs)


def f(a: int, b: int) -> int:
    return a + b

# Prints 3 with the side effect. 
print(wrapper(f, 1, 2))

上面的代码片段有效,并且 mypy 很高兴。但是,我不喜欢 *args**kwargs 的黑匣子,并且希望使 wrapper 不那么通用。如何输入类似这样的内容:

from typing import Callable, ParamSpec, TypeVar

P = ParamSpec("P")
R = TypeVar("R")

# How do I express the fact that a and b are the input params of func?
def wrapper(func: Callable[P, R], a: ?, b: ?) -> R:
    # Run some side effects
    return func(a, b)


def f(a: int, b: int) -> int:
    return a + b

# Mypy should be happy here!
print(wrapper(f, 1, 2)) 

这可能吗?

最佳答案

当您知道将传递给 func 的参数时,您不需要 ParamSpec;普通的 TypeVar 就可以了。

AType = TypeVar('AType')
BType = TypeVar('BType')


def wrapper(func: Callable[[AType, BType], R], a: AType, b: BType) -> R:
    return func(a, b)

如果有其他参数,那么您可以使用Concatenate将已知参数与ParamSpec组合起来。

AType = TypeVar('AType')
BType = TypeVar('BType')
P = ParamSpec('P')


def wrapper(func: Callable[Concatenate[AType, BType, P], R],
            a: AType,
            b: BType,
            *args: P.args,
            **kwargs: P.kwargs) -> R:
    return func(a, b, *args, **kwargs)

关于python - ParamSpec 可以用来输入单个参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73129698/

相关文章:

python-3.x - 在Python 3中播放具有开始时间和结束时间的MP3文件的最佳方式是如何

python - PyCharm 中的列表引发意外类型警告

python - 找到所有长度模式的正则表达式函数?

c++ - 是否考虑函数中的代码?

python - 使用 Python,查找单词列表的字谜

python - 如果总值大于99,如何将十六进制模式设置为lcd?

python - 如何使用 AbstractBaseUser 或 AbstractUser 创建用户。 (登录错误)

python - 使用 Python 获取上周的日期

javascript - 如果不直接传递给requestAnimationFrame,函数体不会执行

c++ - 在同一个函数中使用不同的命名空间