是否可以输入提示lambda函数? [英] Is it possible to type hint a lambda function?
问题描述
当前,在Python中,可以按如下方式提示函数的参数和返回类型:
Currently, in Python, a function's parameters and return types can be type hinted as follows:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
这表示该函数接受两个字符串,并返回一个整数.
Which indicates that the function takes two strings, and returns an integer.
但是,此语法与lambda高度混淆,如下所示:
However, this syntax is highly confusing with lambdas, which look like:
func = lambda var1, var2: var1.index(var2)
我尝试在参数和返回类型上都添加类型提示,但我想不出一种不会引起语法错误的方法.
I've tried putting in type hints on both parameters and return types, and I can't figure out a way that doesn't cause a syntax error.
是否可以输入提示lambda函数?如果不是,是否有计划用于提示类型的lambda,或者出于任何原因(除了明显的语法冲突)为什么不这样做?
Is it possible to type hint a lambda function? If not, are there plans for type hinting lambdas, or any reason (besides the obvious syntax conflict) why not?
推荐答案
您可以在Python 3.6及更高版本中使用
You can, sort of, in Python 3.6 and up using PEP 526 variable annotations. You can annotate the variable you assign the lambda
result to with the typing.Callable
generic:
from typing import Callable
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
这不会将类型提示信息附加到功能对象本身,而不会附加到存储对象的名称空间,但这通常是类型提示所需的全部信息.
This doesn't attach the type hinting information to the function object itself, only to the namespace you stored the object in, but this is usually all you need for type hinting purposes.
但是,您也可以只使用函数语句来代替. lambda
提供的唯一好处是,您可以将一个简单的表达式的函数定义放在一个较大的表达式内部中.但是上述lambda并不是较大表达式的一部分,它只是赋值语句的一部分,并将其绑定到名称.这正是def func(var1: str, var2: str): return var1.index(var2)
语句所能实现的.
However, you may as well just use a function statement instead; the only advantage that a lambda
offers is that you can put a function definition for a simple expression inside a larger expression. But the above lambda is not part of a larger expression, it is only ever part of an assignment statement, binding it to a name. That's exactly what a def func(var1: str, var2: str): return var1.index(var2)
statement would achieve.
请注意,您也不能单独注释*args
或**kwargs
参数,因为Callable
的文档指出:
Note that you can't annotate *args
or **kwargs
arguments separately either, as the documentation for Callable
states:
没有语法指示可选参数或关键字参数;这种函数类型很少用作回调类型.
There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types.
该限制不适用于 PEP 544 协议使用__call__
方法;如果您需要明确表示应接受哪些参数,请使用此选项.您需要Python 3.8 或安装 typing-extensions
项目返港:
That limitation does not apply to a PEP 544 protocol with a __call__
method; use this if you need a expressive definition of what arguments should be accepted. You need Python 3.8 or install the typing-extensions
project for a backport:
from typing-extensions import Protocol
class SomeCallableConvention(Protocol):
def __call__(var1: str, var2: str, spam: str = "ham") -> int:
...
func: SomeCallableConvention = lambda var1, var2, spam="ham": var1.index(var2) * spam
对于lambda
表达式本身,您不能使用任何注释(构建Python类型提示的语法).该语法仅可用于def
函数语句.
For the lambda
expression itself, you can't use any annotations (the syntax on which Python's type hinting is built). The syntax is only available for def
function statements.
来自 PEP 3107-功能注释 :
lambda的语法不支持注释. lambda的语法可以更改,以支持注释,方法是在参数列表周围要求使用括号.但是它已决定不进行此更改,因为:
lambda 's syntax does not support annotations. The syntax of lambda could be changed to support annotations, by requiring parentheses around the parameter list. However it was decided not to make this change because:
- 这将是不兼容的更改.
- Lambda还是被绝育了.
- lambda始终可以更改为函数.
您仍然可以将注释直接附加到对象上,function.__annotations__
属性是可写字典:
You can still attach the annotations directly to the object, the function.__annotations__
attribute is a writable dictionary:
>>> def func(var1: str, var2: str) -> int:
... return var1.index(var2)
...
>>> func.__annotations__
{'var1': <class 'str'>, 'return': <class 'int'>, 'var2': <class 'str'>}
>>> lfunc = lambda var1, var2: var1.index(var2)
>>> lfunc.__annotations__
{}
>>> lfunc.__annotations__['var1'] = str
>>> lfunc.__annotations__['var2'] = str
>>> lfunc.__annotations__['return'] = int
>>> lfunc.__annotations__
{'var1': <class 'str'>, 'return': <class 'int'>, 'var2': <class 'str'>}
当然,当您希望对类型提示运行静态分析器时,像这样的动态注释会为您提供帮助.
Not that dynamic annotations like these are going to help you when you wanted to run a static analyser over your type hints, of course.
这篇关于是否可以输入提示lambda函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!