【发布时间】:2020-08-17 12:39:20
【问题描述】:
有一个函数 (f) 使用一个函数签名 (g)第一组参数和任意数量的关键字参数**kwargs。有没有办法在 (f 中描述的 (g) 的类型签名中包含 **kwargs强>)?
例如:
from typing import Callable, Any
from functools import wraps
import math
def comparator(f: Callable[[Any, Any], bool]) -> Callable[[str], bool]:
@wraps(f)
def wrapper(input_string: str, **kwargs) -> bool:
a, b, *_ = input_string.split(" ")
return f(eval(a), eval(b), **kwargs)
return wrapper
@comparator
def equal(a, b):
return a == b
@comparator
def equal_within(a, b, rel_tol=1e-09, abs_tol=0.0):
return math.isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol)
# All following statements should print `True`
print(equal("1 1") == True)
print(equal("1 2") == False)
print(equal_within("5.0 4.99998", rel_tol=1e-5) == True)
print(equal_within("5.0 4.99998") == False)
函数comparator 用wrapper 包装它的参数f,它将f 的输入作为字符串使用,对其进行解析并使用f 对其进行评估。在这种情况下,Pycharm 会发出警告,指出 return f(eval(a), eval(b), **kwargs) 使用意外参数 **kwargs 调用 f,这与预期的签名不匹配。
This post on Reddit 建议将Any 或... 添加到f 的类型签名中
f: Callable[[Any, Any, ...], bool]f: Callable[[Any, Any, Any], bool]
前者导致 TypeError [1],而后者似乎具有误导性,因为f 接受至少 2 个参数,而不是正好 3 个。
另一种解决方法是将Callable args 定义与... 一样打开f: Callable[..., bool],但我想知道是否有更合适的解决方案。
TypeError: Callable[[arg, ...], result]: each arg must be a type. Got Ellipsis.
【问题讨论】: