如何在不知道所有必要的 args 和 kwargs 的情况下提示键入 Callable?

问题描述 投票:0回答:1

我想编写一个包装器,它接受一个函数参数、它的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 mypy python-typing keyword-argument
1个回答
0
投票

你不能因为错误的类型而导致函数调用失败。 Python 是一种解释型、面向对象的、具有动态语义的高级编程语言。

注意 Python 运行时不强制执行函数和变量类型注释。它们可以被第三方工具使用,例如类型检查器、IDE、linter 等。 —-Python 文档。

您能做的最好的事情就是添加类型提示并希望得到最好的结果。

© www.soinside.com 2019 - 2024. All rights reserved.