如何在类型提示中指定函数类型?
Posted
技术标签:
【中文标题】如何在类型提示中指定函数类型?【英文标题】:How can I specify the function type in my type hints? 【发布时间】:2016-10-16 13:17:01 【问题描述】:我想在我当前的 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,但在那里找不到函数类型提示。
【问题讨论】:
一个函数是Callable
python.org/dev/peps/pep-0483/#fundamental-building-blocks,“我们可能会添加”之前的最后一个要点。
【参考方案1】:
正如@jonrsharpe 在评论中指出的那样,这可以通过typing.Callable
完成:
from typing import AnyStr, Callable
def my_function(name: AnyStr, func: Callable) -> None:
问题是,Callable
本身被翻译成Callable[..., Any]
,这意味着:
可调用对象接受任意数量/类型的 个参数并返回任意类型的值。在大多数情况下,这不是您想要的,因为您将允许传递几乎任何函数。您还希望函数参数和返回类型也被提示。
这就是为什么typing
中的许多types
已被重载以支持表示这些额外类型的子脚本。因此,例如,如果您有一个函数 sum
,它接受两个 int
s 并返回一个 int
:
def sum(a: int, b: int) -> int: return a+b
你的注释是:
Callable[[int, int], int]
即参数在外订阅中下标,返回类型为外订阅中的第二个元素。一般来说:
Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]
【讨论】:
这个typing
的东西将整个python 语言提升了一个档次。
@javadba - 哦,是的,但我仍然不确定在哪个拨号上......顺便说一下 - Callable[[Arg, Types, Here], ...]
对于*args
,**kwargs
,仅关键字 args 怎么样和位置只有参数?他们有没有想过在可调用对象的类型签名中调用约定? ;)
According to the docs, typing.Callable
似乎赞成collections.abc.Callable
:【参考方案2】:
另一个值得注意的有趣点是,您可以使用内置函数type()
来获取内置函数的类型并使用它。
所以你可以有
def f(my_function: type(abs)) -> int:
return my_function(100)
或者类似的东西
【讨论】:
类型提示可以是任何你想要的,但它们并不总是被懒惰地评估。另外,你的函数真的只取builtin_function_or_method
为my_function
吗? lambda
不工作吗?用户定义的函数或绑定方法?
一种非常聪明的方法,至少用于故障排除或头脑风暴
不,你不能,在运行mypy
时,会出现错误:error: Invalid type comment or annotation
note: Suggestion: use type[...] instead of type(...)
。【参考方案3】:
一个最简单和花哨的解决方案是:
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
【讨论】:
这种注解类型的方式不包含任何关于签名的信息:参数数量、这些参数的类型、返回值类型。可以像这样注释函数类型,但我不推荐它。正如其他答案中所建议的那样,最好使用typing.Callable
来代替【参考方案4】:
我想要这个功能的具体用例是在 PyCharm 中启用丰富的代码完成。在这种情况下,使用 Callable
不会导致 PyCharm 建议该对象具有 .__code__
属性,这正是我想要的。
我偶然发现了types
模块和..
from types import FunctionType
允许我用 FunctionType
注释对象,瞧,PyCharm 现在建议我的对象具有 .__code__
属性。
OP 不清楚为什么这种类型的提示对他们有用。 Callable 当然适用于实现.__call__()
的任何东西,但为了进一步说明接口,我提交了types
模块。
可惜 Python 需要两个非常相似的模块。
【讨论】:
相反,vscode 中的 Pylance 仅接受Callable
而不是 FunctionType
有效。以上是关于如何在类型提示中指定函数类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TypeScript 中指定定义为对象文字的箭头函数的类型?
如何在 c# dllimport 中指定 c++ Variant 返回类型
pandas使用select_dtypes函数移除dataframe中指定数据类型的数据列(exclude columns based on the data type in dataframe)
FindResource函数错误代码:1813-找不到映像文件中指定的资源类型 与LoadResource函数错误代码:1812-指定的映像文件不包含资源区域