W pewnym sensie w Pythonie 3.6 i nowszych można używać adnotacji zmiennych PEP 526 . Możesz dodać adnotację do zmiennej, do której przypisujesz lambdawynik, za pomocą typing.Callableogólnego :
from typing import Callable
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
Nie dołącza to informacji wskazujących na typ do samego obiektu funkcji, tylko do przestrzeni nazw, w której przechowywany jest obiekt, ale zwykle jest to wszystko, czego potrzebujesz do celów podpowiadania typu.
Jednak równie dobrze możesz zamiast tego po prostu użyć instrukcji funkcyjnej; jedyną zaletą lambdaoferty jest to, że można umieścić definicję funkcji dla prostego wyrażenia wewnątrz większego wyrażenia. Ale powyższa lambda nie jest częścią większego wyrażenia, jest zawsze tylko częścią instrukcji przypisania, wiążącej ją z nazwą. Dokładnie to def func(var1: str, var2: str): return var1.index(var2)osiągnie stwierdzenie.
Zwróć uwagę, że nie możesz osobno dodawać adnotacji *argsani **kwargsargumentów, ponieważ dokumentacja Callablestwierdza:
Nie ma składni wskazującej argumenty opcjonalne lub słowa kluczowe; takie typy funkcji są rzadko używane jako typy wywołań zwrotnych.
To ograniczenie nie dotyczy protokołu PEP 544 z metodą__call__ ; użyj tego, jeśli potrzebujesz wyrazistej definicji tego, jakie argumenty powinny być akceptowane. Potrzebujesz Pythona 3.8 lub zainstaluj typing-extensionsprojekt dla 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
Dla lambdaekspresji samego , nie można stosować żadnych adnotacji (składni Pythona, na którym zbudowana jest rodzaj podpowiedzi). Składnia jest dostępna tylko dla definstrukcji funkcyjnych.
Z PEP 3107 - Adnotacje funkcji :
Składnia lambda nie obsługuje adnotacji. Składnię lambda można zmienić, aby obsługiwała adnotacje, wymagając nawiasów wokół listy parametrów. Jednak zdecydowano się nie wprowadzać tej zmiany, ponieważ:
- To byłaby niekompatybilna zmiana.
- Lambdy i tak są zneutralizowane.
- Lambdę można zawsze zmienić na funkcję.
Nadal możesz dołączyć adnotacje bezpośrednio do obiektu, function.__annotations__atrybut jest słownikiem z możliwością zapisu:
>>> 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'>}
Oczywiście nie tak dynamiczne adnotacje, jak te, pomogą ci, gdy chcesz uruchomić statyczny analizator nad wskazówkami typu.