在Python 3.6及以上版本中,可以使用PEP 526变量注释。您可以用类型注释分配lambda结果的变量。可调用的通用:
from typing import Callable
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
这并没有将类型提示信息附加到函数对象本身,而是附加到存储对象的名称空间,但这通常是类型提示所需的全部内容。
然而,你也可以只使用函数语句代替;lambda提供的唯一优点是可以将简单表达式的函数定义放在较大的表达式中。但是上面的lambda不是更大表达式的一部分,它只是赋值语句的一部分,将其绑定到一个名称。这正是def func(var1: str, var2: str): return var1.index(var2)语句所能实现的。
请注意,你也不能单独注释*args或**kwargs参数,正如Callable的文档所述:
没有语法来指示可选或关键字参数;这样的函数类型很少用作回调类型。
该限制不适用于具有__call__方法的PEP 544协议;如果你需要一个有表现力的定义来说明什么论点应该被接受,可以使用这个。你需要Python 3.8或为一个backport安装typing-extensions项目:
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 -函数注释:
Lambda的语法不支持注释。lambda的语法可以更改为支持注释,方法是要求在参数列表周围加上圆括号。然而,决定不做这一改变,因为:
这将是一种不相容的变化。
Lambda是被阉割的。
lambda总是可以改变为一个函数。
您仍然可以将注释直接附加到对象(函数)。__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'>}
当然,当您想在类型提示上运行静态分析器时,这样的动态注释并不能帮助您。