Ви можете, наприклад, у Python 3.6 і вище, використовуючи анотації змінних PEP 526 . Ви можете анотувати змінну, якій призначаєте lambdaрезультат, typing.Callableзагальним :
from typing import Callable
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
Це не приєднує інформацію про натяк на тип до самого об'єкта функції, лише до простору імен, у якому ви зберігали об'єкт, але це, як правило, все, що вам потрібно для підказки типу.
Однак ви можете замість цього просто використати оператор функції; єдина перевага, яку lambdaпропонує пропозиція, полягає в тому, що ви можете помістити визначення функції для простого виразу всередину більшого виразу. Але вищезазначена лямбда не є частиною більшого виразу, вона є лише частиною оператора присвоєння, що прив'язує його до імені. Це саме те, чого def func(var1: str, var2: str): return var1.index(var2)можна досягти в заяві.
Зверніть увагу, що ви також не можете анотувати *argsабо **kwargsаргументувати окремо, як зазначено в документації для Callable:
Немає синтаксису для позначення необов’язкових аргументів або аргументів ключових слів; такі типи функцій рідко використовуються як типи зворотного виклику.
Це обмеження не поширюється на протокол PEP 544 із методом__call__ ; використовуйте це, якщо вам потрібно чітко визначити, які аргументи слід прийняти. Вам потрібен Python 3.8 або встановіть typing-extensionsпроект для бекпорта:
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вираження самого , ви не можете використовувати будь-які інструкції ( з синтаксисом , на якому будується тип натякаючи Пайтон). Синтаксис доступний лише дляdef операторів функцій.
З PEP 3107 - Анотації функцій :
синтаксис лямбди не підтримує анотації. Синтаксис лямбда може бути змінений для підтримки анотацій, вимагаючи дужок навколо списку параметрів. Однак було вирішено не вносити цю зміну, оскільки:
- Це була б несумісна зміна.
- Лямбда все одно каструється.
- Лямбду завжди можна змінити на функцію.
Ви все ще можете прикріпити анотації безпосередньо до об’єкта, 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'>}
Звичайно, не такі динамічні анотації допоможуть вам, коли ви хочете запустити статичний аналізатор на підказках вашого типу.