如何在类型提示中指定函数类型?


135

我想在当前的Python 3.5项目中使用类型提示。我的函数应该接收一个函数作为参数。

如何在类型提示中指定类型函数?

import typing

def my_function(name:typing.AnyStr, func: typing.Function) -> None:
    # However, typing.Function does not exist.
    # How can I specify the type function for the parameter `func`?

    # do some processing
    pass

我检查了PEP 483,但在那里找不到函数类型提示。


20
一个功能是Callable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundamental-building-blocks,“我们可能添加”之前的最后一个要点。

Answers:


171

正如@jonrsharpe在评论中指出的,可以使用以下方法完成typing.Callable

from typing import AnyStr, Callable

def my_function(name: AnyStr, func: Callable) -> None:

问题是,Callable将其本身翻译为Callable[..., Any]

一个Callable接受任意数量的/类型的参数,并返回任何类型的值。在大多数情况下,这不是您想要的,因为您几乎可以允许传递任何函数。您也希望提示函数参数和返回类型。

这就是为什么许多typesin typing重载以支持表示这些额外类型的子脚本的原因。因此,例如,如果您有一个函数sum接受两个ints并返回一个int

def sum(a: int, b: int) -> int: return a+b

您的注释为:

Callable[[int, int], int]

也就是说,参数在外部订阅中带有下标,返回类型作为外部订阅中的第二个元素。一般来说:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]

25
这些typing东西将整个python语言提升了一个档次。
javadba

1
@javadba-哦,是的,但是我仍然不确定在哪个拨盘上...顺便说一句- Callable[[Arg, Types, Here], ...]对于*args,,**kwargs仅关键字的args和仅位置的args呢?他们是否没有考虑过可调用对象的类型签名中的调用约定?;)
Tomasz Gandor

10

另一个需要注意的有趣点是,您可以使用内置函数type()来获取内置函数的类型并使用它。所以你可以

def f(my_function: type(abs)) -> int:
    return my_function(100)

或那种形式的东西


类型提示可以是您想要的任何类型,但是它们并不总是被懒惰地求值。另外,您的功能真的只接受builtin_function_or_methodas my_function吗?不会lambda工作吗?用户定义的函数或绑定方法?
Tomasz Gandor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.