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

标签 python lambda

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

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

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

但是,这种语法与 lambdas 很容易混淆,它看起来像:

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

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

是否可以键入提示 lambda 函数?如果没有,是否有类型提示 lambdas 的计划,或者任何原因(除了明显的语法冲突)为什么不呢?

最佳答案

您可以在 Python 3.6 及更高版本中使用 PEP 526 variable annotations .您可以使用 typing.Callable generic 注释您分配 lambda 结果的变量。 :

from typing import Callable

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

这不会将类型提示信息附加到函数对象本身,仅附加到存储对象的命名空间,但这通常是类型提示所需的全部内容。

但是,您也可以只使用函数语句; lambda 提供的唯一优势是您可以将简单表达式的函数定义放在更大的表达式中。但是上面的 lambda 不是更大表达式的一部分,它只是赋值语句的一部分,将它绑定(bind)到一个名称。这正是 def func(var1: str, var2: str): return var1.index(var2) 语句所能达到的效果。

请注意,您也不能单独注释 *args**kwargs 参数,如 Callable 的文档所述:

There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types.

该限制不适用于 PEP 544 protocol with a __call__ method ;如果您需要对应该接受哪些参数进行表达定义,请使用它。您需要 Python 3.8 安装 typing-extensions project对于反向移植:

from typing_extensions import Protocol

class SomeCallableConvention(Protocol):
    def __call__(self, var1: str, var2: str, spam: str = "ham") -> int:
        ...

func: SomeCallableConvention = lambda var1, var2, spam="ham": var1.index(var2) * spam

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

来自 PEP 3107 - Function Annotations :

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:

  • It would be an incompatible change.
  • Lambda's are neutered anyway.
  • The lambda can always be changed to a function.

你仍然可以将注解直接附加到对象上,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'>}

当然,当您想对类型提示运行静态分析器时,像这样的动态注释不会对您有所帮助。

关于python - 是否可以输入提示 lambda 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33833881/

相关文章:

python - 快速 Python PDF 元数据阅读器

python - 从 Python 执行 C++ 代码时出现段错误——在 Mac OS 上使用 Boost.Python

c++ - 当我想在外面抓东西时无法编译 lambda

Java lambda 表达式 : Copy nodes from list to a new list

MethodInfo 调用中的 C# Lambda

c++ - Lambda 函数不能用不同的签名编译

python - Wunderground api 搜索栏

python - 我可以使用带有 http-gzip 或 deflate 压缩的 python 请求库发布数据吗?

python - 在 Django 中渲染 FormSet

c++ - 在C++中使用2个参数和一个lambda函数检查列表中元素的存在