我想编写一个包装器,它接受一个函数参数、它的args和kwargs并执行它们,但有些kwargs是精确已知的,而另一些则是未知的。
示例:
def wrapper(custom_function: MyType, a: int, b: str, *args, **kwargs) -> float:
print(a+3)
print(b)
return custom_function(a, b, *args, **kwargs)
在这个例子中,我想执行第一个参数为
a
、类型为 int
、第二个参数为 b、类型为 str
的任何函数,但我不关心任何其他参数。
使用这个包装器,我希望以下类型提示成功或失败:
def f1(a: int, b: str) -> float:
...
def f2(a: int, b: str, c: float) -> float:
...
def f3(a: float, b: str) -> float:
...
def f4(a: int, b: str, *args, **kwargs) -> float:
...
wrapper(f1, 1, "a") # test 1: succeed
wrapper(f2, 1, "a", 4.6) # test 2: succeed
wrapper(f3, 1, "a") # test 3: fail
wrapper(f4, 1, "a", [1, 2, 3]) # test 4: succeed
我尝试按以下方式使用
typing.Protocol
和 typing.ParamSpec
:
P = ParamSpec("P")
class MyType(Protocol):
def __call__(self, a: int, b: str, P):
....
但它不起作用(测试1和2失败)
我想像这样使用
Callable[...]
将是我能得到的最接近的:
MyType = Callable[..., float]
但是这个解决方案并不令我满意,因为测试 3 会成功,而我希望它失败。
我正在寻找的东西是不可能的吗?
你不能因为错误的类型而导致函数调用失败。 Python 是一种解释型、面向对象的、具有动态语义的高级编程语言。
注意 Python 运行时不强制执行函数和变量类型注释。它们可以被第三方工具使用,例如类型检查器、IDE、linter 等。 —-Python 文档。
您能做的最好的事情就是添加类型提示并希望得到最好的结果。