Python 如何声明函数本身具有特定类型?

Python 如何声明函数本身具有特定类型?,python,types,mypy,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) 在本例中,是否有方法断

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

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
的类型,我希望捕获错误

我并不认为这是显式检查所必需的——只需按常规编写代码,并不断对其运行mypy即可

如果在重构某些代码时意外引入了不一致性,mypy将通知您这些不匹配

因此,如果您的代码执行
metric\u doubler(my\u mean,something)
,并且在不更改
my\u mean
的情况下更改
metric
的定义,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)

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

你是指“返回”类型吗?我是指函数的整个类型:我的意思是,在任何接受
可调用的[List[float],float]
的地方都可以使用它,但我想在代码中用某种方式声明它。据我所知,没有像
my_-mean:Metric
这样的语法被允许。似乎模块级的
my_-mean:Metric
注释可能有用。(我没有试过。)我对3.7打字支持的答案非常感兴趣。你想声明或断言吗?