如何声明一个函数本身具有某种类型?

时间:2018-08-03 19:30:35

标签: python types mypy

假设我有一个将其他函数用作参数的函数:

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的类型,并且想捕获错误。

1 个答案:

答案 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)

我认为第一种形式(将运行时检查与静态检查捆绑在一起)更为有用。