PEP 3107 - Function Annotations.
PEP 482 - Literature Overview for Type Hints.
PEP 484 - Type Hints.
PEP 526 - Syntax for Variable Annotations.
PEP 563 - Postponed Evaluation of Annotations.
Propozycja 'from __future__ import annotations' (Py3.7+).
Adnotacje zmiennych i funkcji nie będą już obliczane w czasie definiowania
zmiennych i funkcji, tylko będzie to odsunięte w czasie.
W słowniku '__annotations__' będzie umieszczona postać napisowa adnotacji.
PEP 649 - Deferred Evaluation Of Annotations Using Descriptors.
Funkcje, klasy i moduły otrzymają nowy atrybut '__annotate__',
który zawiera referencję do funkcji obliczającej adnotacje obiektu.
Redefinicja atrybutu '__annotations__' jako 'data descriptor'.
https://docs.python.org/3/howto/annotations.html
Annotations Best Practices.
Najlepsze praktyki dostępu do adnotacji zależą od wersji Pythona,
ze względu na ciągły rozwój nowych narzędzi.
https://docs.python.org/3/library/inspect.html
'inspect' - Inspect live objects [Py3.5+].
There are four main kinds of services provided by this module:
type checking, getting source code, inspecting classes and functions,
and examining the interpreter stack.
inspect.get_annotations() [Py3.10+].
https://docs.python.org/3/library/typing.html
'typing' - Support for type hints [Py3.5+].
https://typing.readthedocs.io/en/latest/spec/index.html
Specification for the Python type system.
Python wspiera adnotacje dla trzech różnych typów: funkcji, klas i modułów.
Argumenty funkcji mogą mieć adnotacje (ang. annotations) postaci ': expression', następującą po nazwie parametru. Podobnie może być dla parametrów postaci *identifier lub **identifier. Funkcje mogą mieć również adnotację 'return' postaci '-> expression', która następuje po liście parametrów. Jest to składnia do dołączania do funkcji dodatkowych informacji (metadata) dotyczących parametrów i wartości zwracanych. Jest to mechanizm całkowicie opcjonalny. W Pythonie 2 można było tylko w docstringu coś dopowiedzieć.
Wartości adnotacji są dostępne jako wartości słownika '__annotations__', gdzie kluczami są nazwy argumentów funkcji (string).
# Syntax. def nazwa_funkcji(arg1: wyrażenie, arg2: wyrażenie = wartość) -> wyrażenie: instrukcje def nazwa_funkcji(*arguments: wyrażenie, **keywords: wyrażenie = wartość) -> wyrażenie: instrukcje
# Adnotacje funkcji są zwykle używane jako podpowiedzi dla typów. def sum_two_numbers(a: int, b: float) -> complex: return complex(a + b) sum_two_numbers.__annotations__ # {'a': <class 'int'>, 'b': <class 'float'>, 'return': <class 'complex'>}
# https://stackoverflow.com/questions/14379753/what-does-mean-in-python-function-definitions def kinetic_energy(m: 'in kg', v: 'in m/s') -> 'Joules': return 0.5 * m * v**2 # kinetic_energy.__annotations__ to słownik postaci # {'m': 'in kg', 'v': 'in m/s', 'return': 'Joules'}
# Podczas użycia adnotacji zmiennej lub atrybutu klasy # może wystąpić podstawienie wartości. class C: field: int # adnotacja atrybutu klasy def __init__(self) -> None: # konwencja dla konstruktora pass # C.__annotations__ to słownik postaci # {'field': <class 'int'>}
# Adnotacje zmiennych są zwykle używane jako podpowiedzi do typów. import typing count: int = 0 # adnotacja zmiennej i podstawienie some_list: typing.List[int] = [3, 5] some_list: list[int] = [3, 5] # Py3.9+ some_dict: typing.Dict[str, float] = {"a": 1.2} some_dict: dict[str, float] = {"a": 1.2} # Py3.9+ coords: typing.Tuple[int, float] = (12, 3.4) coords: tuple[int, float] = (12, 3.4) # Py3.9+ Url = str # alias typu
# Nazwy Dict, List, Set, FrozenSet używa się do wartości zwracanych. # Dla argumentów funkcji preferuje się abstrakcyjne kolekcje typów, np. # Mapping, Sequence, AbstractSet. from typing import Sequence, Mapping, Set, Iterable, Iterator, Tuple, Text from typing import TypeVar, Callable, Any, AnyStr from typing import Union, Optional, Generic T = TypeVar('T', int, float, complex) Vector = Iterable[Tuple[T, T]] # alias typu def inproduct(v: Vector[T]) -> T: return sum(x*y for x, y in v) # Callable[[Arg1Type, Arg2Type], ReturnType] ogólna postać # Callable[[], str] bez argumentów, zwraca str # Callable[[int, float], None] dwa argumenty (int i float), zwraca None # Text to alias dla str (Py3) lub unicode (Py2) # AnyStr jest zdefiniowane jako TypeVar('AnyStr', Text, bytes) # Sequence[float] # Set[int] # Mapping[int, str] # Mapping jest równowazne Mapping[Any, Any] # Iterable jest równoważne Iterable[Any] # Union[T1, T2, ...] ogólna postać, dopuszczalne typy to T1, T2, ... # Union[int, float] # Optional[T1] jest równoważne Union[T1, None]
Podpowiedzi do typów są i będą opcjonalne, nie są wymuszane w Pythonie. Bywają przydatne dla narzędzi do statycznej analizy typów (mypy, pytype).