是否可以输入提示lambda函数? [英] Is it possible to type hint a lambda function?

查看:76
本文介绍了是否可以输入提示lambda函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆