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

Jon*_*Jon 91 python type-hinting python-3.x python-3.5 mypy

我想在我当前的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
Run Code Online (Sandbox Code Playgroud)

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

Jim*_*ard 115

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

from typing import AnyStr, Callable

def my_function(name: AnyStr, func: Callable) -> None:
Run Code Online (Sandbox Code Playgroud)

问题是,Callable它本身被翻译为Callable[..., Any]:

可调用者接受任意数量的/类型的参数并返回任何类型的值.在大多数情况下,这不是你想要的,因为你几乎可以传递任何函数.您还希望隐藏函数参数和返回类型.

这就是为什么许多typestyping已经超负荷,支持子脚本这表示这些额外的类型.因此,例如,如果你有一个函数sum需要两个ints并返回一个int:

def sum(a: int, b: int) -> int: return a+b
Run Code Online (Sandbox Code Playgroud)

你的注释是:

Callable[[int, int], int]
Run Code Online (Sandbox Code Playgroud)

也就是说,参数在外部订阅中被子脚本化,返回类型作为外部订阅中的第二个元素.一般来说:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]
Run Code Online (Sandbox Code Playgroud)

  • 这些“打字”的东西将整个python语言提升了一个档次。 (5认同)
  • @javadba - 哦,是的,但我仍然不确定在哪个表盘上...顺便说一句 - 对于 `*args`、`* 来说 `Callable[[Arg, Types, Here], ...]` 怎么样? *kwargs`,仅关键字参数和仅位置参数?他们没有考虑过可调用类型签名中的调用约定吗?;) (4认同)
  • [根据文档](https://docs.python.org/3/library/typing.html#typing.Callable),`typing.Callable`似乎支持`collections.abc.Callable`: (2认同)

Joh*_*ell 19

我想要此功能的具体用例是在 PyCharm 中启用丰富的代码完成。使用Callable并没有导致 PyCharm 表明该对象具有.__code__属性,这正是我想要的,在本例中。

\n

我偶然发现了这个types模块,然后..

\n

from types import FunctionType

\n

允许我用 and 注释一个对象FunctionType,voil\xc3\xa0,PyCharm 现在建议我的对象有一个.__code__属性。

\n

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

\n

令人遗憾的是 Python 需要两个非常相似的模块。

\n

  • 相反,vscode 中的 Pylance 仅接受“Callable”而不接受“FunctionType”有效。 (3认同)

小智 13

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

def f(my_function: type(abs)) -> int:
    return my_function(100)
Run Code Online (Sandbox Code Playgroud)

或者那种形式的东西

  • 不,你不能,当运行“mypy”时,这会给出错误:“错误:无效的类型注释或注释”“注意:建议:使用 type[...] 而不是 type(...)”。 (9认同)
  • 类型提示可以是您想要的任何内容,但它们并不总是被延迟评估。另外,你的函数真的只将“builtin_function_or_method”作为“my_function”吗?'lambda' 不起作用吗?用户定义的函数或绑定方法? (3认同)
  • 请注意,“type(abs)”只是“builtin_function_or_method”...我怀疑很多事情都理解(忽略它没有指定参数的事实,并忽略它对于这种情况甚至不正确的事实) (2认同)