是否可以输入提示lambda函数?

时间:2015-11-20 18:45:15

标签: python lambda

目前,在Python中,函数的参数和返回类型可以类型提示如下:

def func(var1: str, var2: str) -> int:
    return var1.index(var2)

表示该函数接受两个字符串,并返回一个整数。

但是,这种语法与lambdas高度混淆,如下所示:

func = lambda var1, var2: var1.index(var2)

我已尝试在参数和返回类型上添加类型提示,但我无法找到一种不会导致语法错误的方法。

是否可以输入提示lambda函数?如果没有,是否有计划暗示lambda,或任何原因(除了显而易见的语法冲突)为什么不呢?

4 个答案:

答案 0 :(得分:34)

从Python 3.6开始,您可以(参见PEP 526):

from typing import Callable
is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)

正如用户c-z所指出的,这与注释非匿名函数的签名不同。如果您在上面的示例中将str变量传递给is_even,Mypy v0.620不会抱怨。

答案 1 :(得分:19)

您可以使用PEP 526 variable annotations在Python 3.6及更高版本中使用。您可以使用typing.Callable generic

为您分配lambda结果的变量添加注释
from typing import Callable

func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)

这不会将类型提示信息附加到函数对象本身,只会附加到存储该对象的命名空间,但这通常只是用于类型提示的所有内容。请注意,您无法以这种方式单独注释*args**kwargs个参数,如Callable所述的文档:

  

没有语法表示可选或关键字参数;这些函数类型很少用作回调类型。

对于lambda表达式本身,您不能使用任何注释(构建Python类型提示的语法)。该语法仅适用于def函数语句。

来自PEP 3107 - Function Annotations

  

lambda的语法不支持注释。通过在参数列表周围要求括号,可以更改lambda的语法以支持注释。但是was decided不要进行此更改,因为:

     
      
  • 这将是一次不相容的变化。
  •   
  • 无论如何,Lambda都是绝育的。
  •   
  • lambda始终可以更改为函数。
  •   

您仍然可以将注释直接附加到对象,function.__annotations__属性是可写字典:

>>> 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'>}

当你想要在类型提示上运行静态分析器时,并不是像这些动态注释会帮助你。

答案 2 :(得分:1)

对于那些在编写代码时只是想快速访问智能感知的人来说,一个近乎黑客的方法是在 lambda 声明之前对参数进行类型注释,做你的工作,并且只然后用参数遮住它。

    x: YourClass
    map(lambda _ :  x.somemethod ...) # x has access to methods defined on YourClass

然后,紧接着:

    x: YourClass # can remove or leave
    map(lambda x:  x.somemethod, ListOfYourObjects) # inner x now shadows the argument

答案 3 :(得分:-1)

不,不可能,没有计划对此进行更改,原因主要是句法上的。