308

我想在我当前的 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,但在那里找不到函数类型提示。

4

4 回答 4

438

正如@jonrsharpe在评论中指出的那样,这可以通过以下方式完成typing.Callable

from typing import AnyStr, Callable

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

问题是,Callable它本身被翻译成Callable[..., Any]这意味着:

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

这就是为什么许多typesintyping已经被重载以支持表示这些额外类型的子脚本。因此,例如,如果您有一个sum需要两个ints 并返回一个 s的函数int

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

您的注释将是:

Callable[[int, int], int]

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

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]
于 2016-09-21T18:36:57.760 回答
17

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

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

或者那种形式的东西

于 2017-10-07T22:24:51.697 回答
2

我想要这个功能的具体用例是在 PyCharm 中启用丰富的代码完成。在这种情况下,使用Callable不会导致 PyCharm 建议该对象具有.__code__我想要的属性。

我偶然发现了types模块和..

from types import FunctionType

允许我注释一个对象FunctionType,瞧,PyCharm 现在建议我的对象有一个.__code__属性。

OP 不清楚为什么这种类型的提示对他们有用。Callable 当然适用于任何实现,.__call__()但为了进一步说明接口,我提交了types模块。

可惜 Python 需要两个非常相似的模块。

于 2021-11-29T18:39:24.240 回答
2

一个最简单和花哨的解决方案是:

def f(my_function: type(lambda x: None)):
    return my_function()

这可以通过以下方式证明:

def poww(num1, num2):
    return num1**num2
    
print(type(lambda x: None) == type(poww))

输出将是: True

于 2021-03-29T20:43:45.907 回答