首页 > 解决方案 > 如何声明一个函数本身具有某种类型?

问题描述

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

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在这种情况下有 type Metric?特别是,真正的用例是当我有很多这样的功能,并且如果我需要更改Metric.

标签: pythontypesmypy

解决方案


我实际上并不认为这是明确检查所必需的——只需照常编写代码,并不断运行 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)

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


推荐阅读