Inne odpowiedzi wykonały dobrą robotę wyjaśniając pisanie kaczek i prostą odpowiedź tzot :
Python nie ma zmiennych, podobnie jak inne języki, w których zmienne mają typ i wartość; ma nazwy wskazujące na obiekty, które znają ich typ.
Jednak jedna interesująca rzecz zmieniła się od 2010 roku (kiedy pytanie zostało zadane po raz pierwszy), a mianowicie implementacja PEP 3107 (zaimplementowana w Pythonie 3). Możesz teraz właściwie określić typ parametru i typ zwracanego typu funkcji:
def pick(l: list, index: int) -> int:
return l[index]
Widzimy tutaj, że pickbierze 2 parametry, listę li liczbę całkowitą index. Powinien także zwrócić liczbę całkowitą.
Tutaj sugeruje się, że ljest to lista liczb całkowitych, które możemy zobaczyć bez większego wysiłku, ale w przypadku bardziej złożonych funkcji może być nieco mylące, co powinna zawierać lista. Chcemy również, aby domyślna wartość wynosiła index0. Aby rozwiązać ten problem, możesz pickzamiast tego napisać w następujący sposób:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Zauważ, że teraz wstawiamy ciąg jako typ l, który jest składniowo dozwolony, ale nie nadaje się do parsowania programowego (do którego wrócimy później).
Ważne jest, aby pamiętać, że Python nie podniesie wartości, TypeErrorjeśli przejdziesz do float index, przyczyną tego jest jeden z głównych punktów filozofii projektowania Pythona: „Wszyscy zgadzamy się tutaj na dorosłych” , co oznacza, że oczekuje się bądź świadomy tego, co możesz przekazać do funkcji, a czego nie. Jeśli naprawdę chcesz napisać kod, który wyrzuca błędy TypeErrors, możesz użyć isinstancefunkcji, aby sprawdzić, czy przekazany argument jest poprawnego typu lub jego podklasy w następujący sposób:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
Więcej o tym, dlaczego tak rzadko powinieneś to robić, a o tym, co powinieneś zrobić, omówiono w następnej sekcji i w komentarzach.
PEP 3107 nie tylko poprawia czytelność kodu, ale ma także kilka pasujących przypadków użycia, o których możesz przeczytać tutaj .
Adnotacja typu zyskała dużo większą uwagę w Pythonie 3.5 dzięki wprowadzeniu PEP 484, który wprowadza standardowy moduł do wskazówek typu.
Te wskazówki dotyczące typów pochodzą od mypy sprawdzania typu ( GitHub ), która jest teraz zgodna z PEP 484 .
Z modułem do pisania dołączony jest dość obszerny zbiór wskazówek dotyczących typów, w tym:
List, Tuple, Set, Map- do list, tuple, seti mapodpowiednio.
Iterable - przydatne dla generatorów.
Any - kiedy może być cokolwiek.
Union- kiedy może to być cokolwiek w ramach określonego zestawu typów, w przeciwieństwie do Any.
Optional- kiedy może to być Brak. Stenografia dla Union[T, None].
TypeVar - stosowany z lekami generycznymi.
Callable - używany głównie do funkcji, ale może być wykorzystany do innych wywołań.
Są to najczęstsze wskazówki dotyczące typów. Pełną listę można znaleźć w dokumentacji modułu do pisania .
Oto stary przykład wykorzystujący metody adnotacji wprowadzone w module pisania:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
Jedną z potężnych funkcji jest Callablemożliwość wpisywania metod adnotacji, które przyjmują funkcję jako argument. Na przykład:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
Powyższy przykład może stać się bardziej precyzyjny z użyciem TypeVarzamiast Any, ale zostało to pozostawione jako ćwiczenie dla czytelnika, ponieważ uważam, że już wypełniłem moją odpowiedź zbyt dużą ilością informacji o cudownych nowych funkcjach włączonych przez podpowiedzi typu.
Wcześniej, gdy udokumentowano jeden kod Pythona, na przykład Sphinx, niektóre z powyższych funkcji można było uzyskać pisząc dokumenty w formacie takim jak ten:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
Jak widać, wymaga to kilku dodatkowych wierszy (dokładna liczba zależy od tego, jak wyraźny chcesz być i jak formatujesz dokumenty). Ale teraz powinno być dla ciebie jasne, w jaki sposób PEP 3107 stanowi alternatywę, która jest na wiele (wszystkich?) Sposobów lepsza. Jest to szczególnie prawdziwe w połączeniu z PEP 484, który, jak widzieliśmy, zapewnia standardowy moduł, który definiuje składnię dla tego typu wskazówek / adnotacji, które mogą być używane w taki sposób, że są jednoznaczne i precyzyjne, a jednocześnie elastyczne, tworząc potężna kombinacja.
Moim osobistym zdaniem jest to jedna z największych funkcji Pythona w historii. Nie mogę się doczekać, aż ludzie zaczną wykorzystywać jego moc. Przepraszam za długą odpowiedź, ale tak się dzieje, kiedy się ekscytuję.
Przykład kodu Pythona, który intensywnie korzysta z podpowiedzi typu, można znaleźć tutaj .