提问人:Carlos 提问时间:9/18/2023 最后编辑:Carlos 更新时间:9/18/2023 访问量:52
函数参数的类型注释 [duplicate]
Type annotation for the arguments of a function [duplicate]
问:
请看下面的例子:
from typing import TypeVar
from collections.abc import Callable
T0 = TypeVar("T0")
T1 = TypeVar("T1")
T2 = TypeVar("T2")
def my_fun(a: str, b: int) -> None:
print(int(a) + b)
return None
def fun_caller(f: Callable[[T0, T1], T2], *args: tuple[T0, T1]) -> T2:
return f(*args)
fun_caller(my_fun, "1", 2)
我想将一个函数后跟该函数的参数传递给另一个函数。
上面的示例起作用,因为类型检查器知道 中使用了正确数量的参数和正确的参数类型。但是,此示例仅适用于具有 2 个输入参数的函数,我想将其推广到任意数量的未知类型的参数。fun_caller(my_fun, "1", 2)
另请注意以下示例:
from typing import TypeVar, Any
from collections.abc import Callable
T = TypeVar("T")
def my_fun(a: str, b: int) -> None:
print(int(a) + b)
return None
def fun_caller(f: Callable[..., T], *args: tuple[Any, ...]) -> T:
return f(*args)
fun_caller(my_fun, 0, 2, "a") # I want the type checker to complain, e.g.,
# first arg should be str
# there should only be 2 args, not 3
这是行不通的,因为现在类型检查器不会抱怨无效的参数数量和无效的参数类型。此代码将按预期引发,但我想在类型检查器中捕获此问题。TypeError: my_fun() takes 2 positional arguments but 3 were given
答:
1赞
Carlos
9/18/2023
#1
刚刚发现这可以通过 ParamSpec 来实现。例:
# pyright: strict
from typing import ParamSpec, TypeVar
from collections.abc import Callable
P = ParamSpec("P")
T = TypeVar("T")
def my_fun1(a: str, b: int) -> None:
print(int(a) + b)
return None
def my_fun2(a: str, b: int, c: float) -> None:
print(int(a) + b*c)
return None
def fun_caller(f: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
return f(*args, **kwargs)
fun_caller(my_fun1, "1", 2) # no issues reported
fun_caller(my_fun2, "1", 2, 3.14) # no issues reported
fun_caller(my_fun2, c=3.14, a="1", b=2) # no issues reported
fun_caller(my_fun1, 0, 2, "a") # Argument of type "Literal[0]" cannot be assigned to parameter of type "str"
# Expected 2 positional arguments
评论
ParamSpec