您可以在 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 不是更大表达式的一部分,它只是赋值语句的一部分,将它绑定到一个名称。这正是def func(var1: str, var2: str): return var1.index(var2) 语句所能达到的效果。
请注意,您也不能单独注释 *args 或 **kwargs 参数,正如 Callable 的文档所述:
没有语法来指示可选或关键字参数;此类函数类型很少用作回调类型。
该限制不适用于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 的语法不支持注解。可以通过在参数列表周围使用括号来更改 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'>}
当然,当您想对类型提示运行静态分析器时,像这样的动态注释不会对您有所帮助。