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 lambda
wynik, za pomocą typing.Callable
ogó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ą lambda
oferty 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 *args
ani **kwargs
argumentów, ponieważ dokumentacja Callable
stwierdza:
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-extensions
projekt 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 lambda
ekspresji samego , nie można stosować żadnych adnotacji (składni Pythona, na którym zbudowana jest rodzaj podpowiedzi). Składnia jest dostępna tylko dla def
instrukcji 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.