В настоящее время в Python параметры функции и типы возвращаемого значения могут иметь следующий тип:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
Это означает, что функция принимает две строки и возвращает целое число.
Однако этот синтаксис сильно сбивает с толку лямбда-выражения, которые выглядят так:
func = lambda var1, var2: var1.index(var2)
Я пробовал вводить подсказки типов как для параметров, так и для возвращаемых типов, и я не могу найти способ, который не вызывает синтаксической ошибки.
Можно ли ввести подсказку лямбда-функции? Если нет, то есть ли планы использовать лямбды с подсказками типов или по какой-либо причине (помимо очевидного конфликта синтаксиса), почему бы и нет?
key
аргумента дляsorted
встроенного. Я действительно не вижу смысла добавлять подсказки типа в таком ограниченном контексте. Кроме того, использование аннотаций переменных PEP-526 для добавления подсказок типаlambda
полностью упускает суть, ИМХО.lambda
Синтаксис предназначен для определения скрытых функций. Какой смысл использоватьlambda
и сразу привязывать к переменной? Просто используйтеdef
!Ответы:
Вы можете вроде как в 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'>}
Конечно, не то, чтобы подобные динамические аннотации помогли вам, когда вы захотели запустить статический анализатор над подсказками типа.
источник
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
то почему не лучший ответdef func(var1: str, var2: str) -> int: return var1.index(var2)
???Начиная с Python 3.6 вы можете (см. PEP 526 ):
from typing import Callable is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)
источник
x
?is_even
Функция - это,Callable
которая ожидает одинint
аргумент, поэтому x - этоint
.is_even('x')
вызывает ошибку типа.Нет, это невозможно, нет планов изменить это, и причины в основном синтаксические.
источник