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