假设我有一个将其他函数用作参数的函数:
Metric = Callable[List[float], float]
def metric_doubler(metric: Metric, lst: List[float]):
return 2*metric(lst)
我想编写其他函数,并声明它们具有类型Metric
,例如
def my_mean(lst: List[float]) -> float:
return sum(lst)/len(lst)
在这种情况下,是否可以断言my_mean
的类型为Metric
?特别地,真正的用例是当我有很多这样的功能时,如果我需要更改Metric
的类型,并且想捕获错误。
答案 0 :(得分:1)
我实际上并不认为这是显式检查所必需的-只需正常编写代码,并不断对其进行mypy处理即可。
如果您最终在重构某些代码时意外引入了不一致,则mypy会通知您这些不匹配之处。
因此,如果您有执行metric_doubler(my_mean, something)
的代码并更改了Metric
的定义而不更改my_mean
,则mypy将抱怨该函数调用。
(这是静态键入的好处之一!如果键入了所有内容,则您的工具可以为您检测到错误和不匹配,因此您可以更放心地进行重构-您通常不需要添加任何额外的工作类型。
如果要绝对确保所有内容都匹配,则可以添加一些额外的单元测试。例如。也许添加如下所示的单元测试:
def test_my_mean() -> None:
assert metric_doubler(my_mean, something) == something_else
然后,针对完整的代码库和测试运行mypy。
或更简单地:
def expects_metric(x: Metric) -> None: pass
def test_my_mean() -> None:
expect_metric(my_mean)
我认为第一种形式(将运行时检查与静态检查捆绑在一起)更为有用。