Adnotacje funkcji: PEP-3107
Natrafiłem na fragment kodu demonstrujący adnotacje funkcji Python3. Koncepcja jest prosta, ale nie mam pojęcia, dlaczego zostały one zaimplementowane w Pythonie3 ani w jakimkolwiek dobrym zastosowaniu. Może SO może mnie oświecić?
Jak to działa:
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
... function body ...
Wszystko, co następuje po dwukropku po argumencie to „adnotacja”, a informacje następujące po nim ->
to adnotacja dotycząca wartości zwracanej przez funkcję.
foo.func_annotations zwróci słownik:
{'a': 'x',
'b': 11,
'c': list,
'return': 9}
Jakie jest znaczenie posiadania tego dostępnego?
python
function
annotations
python-3.x
agscala
źródło
źródło
foo.func_annotations
byćfoo.__annotations__
w python3?def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
znaczyOdpowiedzi:
Myślę, że to jest naprawdę świetne.
Mając doświadczenie akademickie, mogę powiedzieć, że adnotacje okazały się nieocenione we włączaniu inteligentnych analizatorów statycznych dla języków takich jak Java. Na przykład, możesz zdefiniować semantykę, taką jak ograniczenia stanu, wątki, do których można uzyskać dostęp, ograniczenia architektury itp., I istnieje wiele narzędzi, które mogą je następnie odczytać i przetworzyć, aby zapewnić gwarancje wykraczające poza to, co otrzymujesz od kompilatorów. Możesz nawet napisać rzeczy, które sprawdzają warunki wstępne / warunki końcowe.
Wydaje mi się, że coś takiego jest szczególnie potrzebne w Pythonie z powodu słabszego pisania, ale tak naprawdę nie było konstrukcji, które uczyniłyby to prostym i częścią oficjalnej składni.
Istnieją inne zastosowania adnotacji, których nie można zagwarantować. Widzę, jak mogę zastosować moje narzędzia Java do Pythona. Na przykład mam narzędzie, które pozwala przypisać specjalne ostrzeżenia do metod i daje wskazówki, kiedy je wywołujesz, że powinieneś przeczytać ich dokumentację (np. Wyobraź sobie, że masz metodę, której nie wolno wywoływać z wartością ujemną, ale nie intuicyjnie z nazwy). Z adnotacjami mógłbym technicznie napisać coś takiego dla Pythona. Podobnie, narzędzie, które organizuje metody w dużej klasie na podstawie tagów, można napisać, jeśli istnieje oficjalna składnia.
źródło
Adnotacje funkcji są tym, co z nich zrobisz.
Mogą służyć do dokumentacji:
Mogą być używane do sprawdzania stanu wstępnego:
Zobacz także http://www.python.org/dev/peps/pep-0362/, aby dowiedzieć się, jak zaimplementować sprawdzanie typów.
źródło
Mass
iVelocity
zamiast tego.def kinetic_energy(mass: 'in kilograms', velocity: 'in meters per second') -> float:
również pokazać typ zwrotu. To moja ulubiona odpowiedź tutaj.return
adnotacji? Wydaje się, że nie pojawia się wlocals
To dość późna odpowiedź, ale ODPOWIEDŹ, obecnie najlepszym zastosowaniem adnotacji funkcji jest PEP-0484 i MyPy .
Używane tak:
źródło
list(fib('a'))
pomocą Twojej przykładowej funkcji, Python 3.7 z radością przyjmuje argument i narzeka, że nie ma możliwości porównania ciągu i int.Aby dodać konkretny przykład dobrego wykorzystania z mojej odpowiedzi tutaj , w połączeniu z dekoratorami, można zrobić prosty mechanizm dla wielu metod.
i przykład użycia:
Można to zrobić, dodając typy do dekoratora jako oryginalny post Guido pokazuje , ale adnotacji do samych parametrów jest lepsze, ponieważ pozwala uniknąć niewłaściwego dopasowania parametrów i typów.
Uwaga : w Pythonie możesz uzyskać dostęp do adnotacji,
function.__annotations__
a niefunction.func_annotations
tak, jakfunc_*
styl został usunięty w Pythonie 3.źródło
function = self.typemap.get(types)
że nie zadziała, gdy w grę wchodzą podklasy. W takim przypadku prawdopodobnie będziesz musiał przejść przeztypemap
usingisinnstance
. Zastanawiam się, czy dobrze@overload
sobie z tym radzi__annotations__
Todict
, że nie zapewnia argumenty porządku, więc ten fragment czasami zawodzą. Polecam zmieniająctypes = tuple(...)
sięspec = inspect.getfullargspec(function)
potemtypes = tuple([spec.annotations[x] for x in spec.args])
.Uri udzielił już właściwej odpowiedzi, więc oto mniej poważna odpowiedź: możesz więc skrócić swoje dokumenty.
źródło
Gdy po raz pierwszy zobaczyłem adnotacje, pomyślałem: „Świetnie! Wreszcie mogę włączyć sprawdzanie typów!” Oczywiście nie zauważyłem, że adnotacje nie są w rzeczywistości wymuszane.
Postanowiłem więc napisać prosty dekorator funkcji, aby je egzekwować :
Dodałem go do biblioteki Zapewnij .
źródło
Minęło dużo czasu, odkąd o to zadano, ale przykładowy fragment podany w pytaniu pochodzi (jak tam również stwierdzono) z PEP 3107 i na końcu przykładu PEP Podano również przypadki użycia, które mogą odpowiedzieć na pytanie z punktu PEP zobacz;)
Poniższy cytat pochodzi z PEP3107
Przypadków użycia
W trakcie omawiania adnotacji podniesiono szereg przypadków użycia. Niektóre z nich zostały tutaj przedstawione, pogrupowane według rodzaju przekazywanych informacji. Uwzględniono również przykłady istniejących produktów i pakietów, w których można by użyć adnotacji.
Więcej informacji na temat konkretnych punktów (wraz z odniesieniami) można znaleźć w PEP
źródło
Python 3.X (tylko) również uogólnia definicję funkcji, aby umożliwić przypisywanie argumentów i wartości zwracanych do wartości obiektu do użycia w rozszerzeniach .
Jego META-dane do wyjaśnienia, aby bardziej szczegółowo opisać wartości funkcji.
Adnotacje są kodowane
:value
po nazwie argumentu i przed wartością domyślną oraz->value
po liście argumentów.Są one gromadzone w
__annotations__
atrybucie funkcji, ale w innym przypadku nie są traktowane jako specjalne przez sam Python:PRZYKŁAD:
Plik
typeannotations
Moduł dostarcza zestaw narzędzi do sprawdzania typu i rodzaju wnioskowania kodu Pythona. Zawiera również zestaw typów przydatnych do opisywania funkcji i obiektów.Narzędzia te są przeznaczone głównie do użytku w analizatorach statycznych, takich jak lintery, biblioteki uzupełniania kodu i środowiska IDE. Dodatkowo dostępne są dekoratory do przeprowadzania kontroli w czasie wykonywania. Sprawdzanie typów w czasie wykonywania nie zawsze jest dobrym pomysłem w Pythonie, ale w niektórych przypadkach może być bardzo przydatne.
https://github.com/ceronman/typeannotations
Jak pisanie pomaga pisać lepszy kod
PEP 526 - Składnia adnotacji zmiennych
https://www.python.org/dev/peps/pep-0526/
https://www.attrs.org/en/stable/types.html
źródło
Pomimo wszystkich opisanych tutaj zastosowań, jedynym możliwym do wyegzekwowania i najprawdopodobniej wymuszonym użyciem adnotacji będzie wskazówki dotyczące typów .
Obecnie nie jest to w żaden sposób wymuszane, ale sądząc po PEP 484, przyszłe wersje Pythona będą zezwalać tylko na typy jako wartości dla adnotacji.
Cytowanie A co z obecnymi zastosowaniami adnotacji? :
Chociaż nie widziałem jeszcze żadnych cichych wycofań w 3.6, zamiast tego można to z powodzeniem podnieść do 3.7.
Tak więc, nawet jeśli mogą istnieć inne dobre przypadki użycia, najlepiej zachować je wyłącznie do podpowiedzi typu, jeśli nie chcesz zmieniać wszystkiego w przyszłości, w której to ograniczenie jest na miejscu.
źródło
Jako nieco opóźnioną odpowiedź, kilka moich pakietów (marrow.script, WebCore itp.) Używa adnotacji, jeśli są dostępne, do deklarowania typowania (tj. Przekształcania wartości przychodzących z sieci, wykrywania, które argumenty są przełącznikami logicznymi itp.) jak wykonać dodatkowe znaczniki argumentów.
Marrow Script buduje kompletny interfejs wiersza poleceń dla dowolnych funkcji i klas oraz pozwala na definiowanie dokumentacji, rzutowania i wartości domyślnych pochodzących z wywołań zwrotnych za pośrednictwem adnotacji, z dekoratorem obsługującym starsze środowiska wykonawcze. Wszystkie moje biblioteki korzystające z adnotacji obsługują następujące formularze:
Obsługa „gołych” ciągów dokumentów lub funkcji rzutowania typów umożliwia łatwiejsze mieszanie z innymi bibliotekami, które obsługują adnotacje. (To znaczy mam kontroler sieciowy używający rzutowania typów, który również jest ujawniany jako skrypt wiersza poleceń).
Edytowano, aby dodać: Zacząłem również korzystać z pakietu TypeGuard przy użyciu asercji w czasie programowania do walidacji. Korzyści: w przypadku uruchomienia z włączoną „optymalizacją” (
-O
/PYTHONOPTIMIZE
env var) pomija się kontrole, które mogą być kosztowne (np. Rekurencyjne), z założeniem, że aplikacja została poprawnie przetestowana w fazie rozwoju, więc kontrole powinny być niepotrzebne w środowisku produkcyjnym.źródło
Adnotacje mogą służyć do łatwego modularyzacji kodu. Np. Moduł dla programu, który obsługuję, mógłby po prostu zdefiniować metodę taką jak:
i moglibyśmy poprosić użytkownika o rzecz o nazwie „param1”, która jest „potrzebna do liczenia” i powinna być wartością „int”. W końcu możemy nawet przekonwertować ciąg podany przez użytkownika na żądany typ, aby uzyskać jak najbardziej bezproblemowe doświadczenie.
Zobacz nasz obiekt metadanych funkcji dla klasy open source, która pomaga w tym i może automatycznie pobierać potrzebne wartości i konwertować je na dowolny pożądany typ (ponieważ adnotacja jest metodą konwersji). Nawet IDE poprawnie pokazują autouzupełnienia i zakładają, że typy są zgodne z adnotacjami - idealnie pasują.
źródło
Jeśli spojrzysz na listę zalet Cythona, główną z nich jest możliwość poinformowania kompilatora, jakiego typu jest obiekt Pythona.
Mogę wyobrazić sobie przyszłość, w której Cython (lub podobne narzędzia, które kompilują część twojego kodu Pythona) będą używać składni adnotacji do wykonywania swojej magii.
źródło
multiply
funkcję do działania tylko na liczbach całkowitych, kiedy'na' * 8 + ' batman!'
jest całkowicie poprawna? ;)