【问题标题】:How to declare that a function itself has a certain type?如何声明一个函数本身具有某种类型?
【发布时间】:2019-01-11 17:24:06
【问题描述】:

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

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 的类型时想要捕获错误。

【问题讨论】:

  • 你的意思是“返回”类型吗?
  • 我的意思是函数的整个类型:my_mean 可以在任何接受Callable[List[float], float] 的地方使用,但我想在代码中以某种方式声明它。据我所知,没有像 my_mean: Metric 这样的语法允许
  • 似乎模块级别的my_mean: Metric 注释可能会做一些有用的事情。 (我没试过。)
  • 我会对 3.7 输入支持的答案非常感兴趣
  • 您要声明或断言?

标签: python types mypy


【解决方案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)

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

【讨论】:

    猜你喜欢
    • 2019-07-20
    • 2022-11-25
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多