Obecnie w Pythonie parametry funkcji i typy zwracane mogą mieć następujące wskazówki:
def func(var1: str, var2: str) -> int:
return var1.index(var2)
Co oznacza, że funkcja przyjmuje dwa ciągi i zwraca liczbę całkowitą.
Jednak ta składnia jest bardzo myląca z lambdami, które wyglądają następująco:
func = lambda var1, var2: var1.index(var2)
Próbowałem umieścić wskazówki dotyczące typów zarówno dla parametrów, jak i typów zwracanych, ale nie mogę znaleźć sposobu, który nie powoduje błędu składniowego.
Czy można wpisać podpowiedź do funkcji lambda? Jeśli nie, czy istnieją plany dotyczące wyrażeń lambda podpowiadających typ lub z jakiegoś powodu (poza oczywistym konfliktem składni), dlaczego nie?
key
argument funkcjisorted
wbudowanej. Naprawdę nie widzę sensu w dodawaniu wskazówek dotyczących typów w tak ograniczonych kontekstach. Ponadto użycie adnotacji zmiennych PEP-526 w celu dodania wskazówek dotyczących typulambda
całkowicie mija się z celem, IMHO.lambda
Składnia ma na celu zdefiniowanie anonimowych funkcje. Jaki jest sens używanialambda
i natychmiastowego wiązania go ze zmienną? Po prostu użyjdef
!Odpowiedzi:
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 todef 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ż dokumentacjaCallable
stwierdza: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 zainstalujtyping-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 dladef
instrukcji funkcyjnych.Z PEP 3107 - Adnotacje funkcji :
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.
źródło
func: Callable[[str, str], int] = lambda var1, var2: var1.index(var2)
dlaczego nie jest lepsza odpowiedźdef func(var1: str, var2: str) -> int: return var1.index(var2)
???Od Pythona 3.6 możesz (zobacz PEP 526 ):
from typing import Callable is_even: Callable[[int], bool] = lambda x: (x % 2 == 0)
źródło
x
?is_even
Funkcja to a,Callable
która oczekuje jednegoint
argumentu, więc x jestint
.is_even('x')
powoduje błąd typu.Nie, nie jest to możliwe, nie ma planów zmiany tego, a przyczyny są przede wszystkim syntaktyczne.
źródło