Содержание страницы
typing – Поддержка аннотаций типов¶typing – Support for type hints
Новое в версии 3.5.
Исходный код: Lib/typing.py
Примечание
Среда выполнения Python не проверяет аннотации типов функций и переменных. Они могут использоваться сторонними инструментами, такими как средства проверки типов, IDE, линтеры и т. д.
Этот модуль обеспечивает поддержку подсказок типов во время выполнения в соответствии с
PEP 484, PEP 526, PEP 544, PEP 586, PEP 589 и PEP 591.
Самая базовая поддержка включает типы Any, Union,
Tuple, Callable, TypeVar и
Generic. Полную спецификацию см. в PEP 484. Для
упрощённого введения в подсказки типов см. PEG 483.
Функция ниже принимает и возвращает строку и аннотирована следующим образом:
def greeting(name: str) -> str:
return 'Hello ' + name
В функции greeting аргумент name ожидается типа str, а возвращаемый тип – str. Подтипы допускаются в качестве аргументов.
Псевдонимы типов¶Type aliases
Псевдоним типа определяется присваиванием типа псевдониму. В этом примере
Vector и List[float] будут рассматриваться как взаимозаменяемые синонимы:
from typing import List
Vector = List[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# Проходит проверку типов; список чисел с плавающей запятой считается Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
Псевдонимы типов полезны для упрощения сложных сигнатур типов. Например:
from typing import Dict, Tuple, Sequence
ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None:
...
# Статическая проверка типов будет считать предыдущую сигнатуру типа как
# полностью эквивалентную этой.
def broadcast_message(
message: str,
servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
...
Обратите внимание, что None как аннотация типа является особым случаем и заменяется на type(None).
NewType¶
Для создания отдельных типов используется вспомогательная функция NewType():
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
Статический проверщик типов будет рассматривать новый тип как подкласс исходного типа. Это полезно для выявления логических ошибок:
def get_user_name(user_id: UserId) -> str:
...
# Проходит проверку типов.
user_a = get_user_name(UserId(42351))
# Не проходит проверку типов; int не является UserId.
user_b = get_user_name(-1)
Можно по-прежнему выполнять все операции int над переменной типа UserId,
но результат всегда будет типа int. Это позволяет передавать UserId
везде, где может ожидаться int, но предотвращает случайное создание UserId
недопустимым способом:
# 'output' имеет тип 'int', а не 'UserId'
output = UserId(23413) + UserId(54341)
Обратите внимание, что эти проверки выполняются только статическим анализатором типов. Во время выполнения оператор Derived = NewType('Derived', Base) превращает Derived в функцию, которая немедленно возвращает любой переданный ей параметр. Это означает, что выражение Derived(some_value) не создаёт новый класс и не вносит никаких накладных расходов сверх обычного вызова функции.
Точнее, выражение some_value is Derived(some_value) во время выполнения всегда
истинно.
Это также означает, что невозможно создать подтип Derived, поскольку во время выполнения это тождественная функция, а не реальный тип:
from typing import NewType
UserId = NewType('UserId', int)
# Завершается ошибкой во время выполнения и не проходит проверку типов.
class AdminUserId(UserId): pass
Однако можно создать NewType() на основе «производного» NewType:
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
и проверка типов для ProUserId будет работать как ожидается.
Подробнее см. PEP 484.
Примечание
Напомним, что использование псевдонима типа объявляет два типа эквивалентными друг другу. Использование Alias = Original заставит статический анализатор типов считать Alias точно эквивалентным Original во всех случаях. Это полезно, когда требуется упростить сложные сигнатуры типов.
В отличие от этого, NewType объявляет один тип подтипом другого. Использование Derived = NewType('Derived', Original) заставит статический анализатор типов считать Derived подклассом Original, что означает, что значение типа Original не может использоваться там, где ожидается значение типа Derived. Это полезно для предотвращения логических ошибок с минимальными затратами времени выполнения.
Новое в версии 3.5.2.
Callable¶
Фреймворки, ожидающие функции обратного вызова с определённой сигнатурой, могут быть аннотированы с помощью Callable[[Arg1Type, Arg2Type], ReturnType].
Например:
from typing import Callable
def feeder(get_next_item: Callable[[], str]) -> None:
# Тело
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
# Тело
Можно объявить возвращаемый тип вызываемого объекта, не указывая сигнатуру вызова, заменив список аргументов многоточием в аннотации типа: Callable[..., ReturnType].
Обобщённые типы¶Generics
Поскольку информацию о типах объектов, хранящихся в контейнерах, нельзя статически вывести обобщённым способом, абстрактные базовые классы были расширены для поддержки параметризации типами, чтобы обозначить ожидаемые типы элементов контейнера.
from typing import Mapping, Sequence
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
Обобщения (дженерики) можно параметризовать с помощью новой фабрики, доступной в typing, которая называется TypeVar.
from typing import Sequence, TypeVar
T = TypeVar('T') # Объявить переменную типа
def first(l: Sequence[T]) -> T: # Обобщённая функция
return l[0]
Пользовательские обобщённые типы¶User-defined generic types
Пользовательский класс можно определить как обобщённый класс.
from typing import TypeVar, Generic
from logging import Logger
T = TypeVar('T')
class LoggedVar(Generic[T]):
def __init__(self, value: T, name: str, logger: Logger) -> None:
self.name = name
self.logger = logger
self.value = value
def set(self, new: T) -> None:
self.log('Set ' + repr(self.value))
self.value = new
def get(self) -> T:
self.log('Get ' + repr(self.value))
return self.value
def log(self, message: str) -> None:
self.logger.info('%s: %s', self.name, message)
Generic[T] в качестве базового класса определяет, что класс LoggedVar принимает один параметр типа T. Это также делает T допустимым типом внутри тела класса.
Базовый класс Generic определяет __class_getitem__(), что делает LoggedVar[t] допустимым в качестве типа:
from typing import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
Обобщённый тип может иметь любое количество переменных типа, и эти переменные могут быть ограничены:
from typing import TypeVar, Generic
...
T = TypeVar('T')
S = TypeVar('S', int, str)
class StrangePair(Generic[T, S]):
...
Каждый аргумент-переменная типа для Generic должен быть уникальным. Поэтому такой код некорректен:
from typing import TypeVar, Generic
...
T = TypeVar('T')
class Pair(Generic[T, T]): # НЕДОПУСТИМО
...
Можно использовать множественное наследование с Generic:
from typing import TypeVar, Generic, Sized
T = TypeVar('T')
class LinkedList(Sized, Generic[T]):
...
При наследовании от обобщённых классов некоторые переменные типа могут быть зафиксированы:
from typing import TypeVar, Mapping
T = TypeVar('T')
class MyDict(Mapping[str, T]):
...
В этом случае MyDict имеет один параметр – T.
Использование обобщённого класса без указания параметров типа подразумевает Any для каждой позиции. В следующем примере MyIterable не является обобщённым, но неявно наследуется от Iterable[Any]:
from typing import Iterable
class MyIterable(Iterable): # То же, что и Iterable[Any].
Пользовательские обобщённые псевдонимы типов также поддерживаются. Примеры:
from typing import TypeVar, Iterable, Tuple, Union
S = TypeVar('S')
Response = Union[Iterable[S], int]
# Тип возврата здесь такой же, как Union[Iterable[str], int]
def response(query: str) -> Response[str]:
...
T = TypeVar('T', int, float, complex)
Vec = Iterable[Tuple[T, T]]
def inproduct(v: Vec[T]) -> T: # То же, что Iterable[Tuple[T, T]]
return sum(x*y for x, y in v)
Изменено в версии 3.7: Generic больше не имеет собственного метакласса.
Пользовательский обобщённый класс может иметь ABC в качестве базовых классов без конфликта метаклассов. Обобщённые метаклассы не поддерживаются. Результат параметризации обобщений кэшируется, и большинство типов в модуле typing являются хешируемыми и сравнимыми на равенство.
Тип Any¶The Any type
Особым видом типа является Any. Статический проверяющий типов будет считать каждый тип совместимым с Any, а Any – совместимым с каждым типом.
Это означает, что над значением типа Any можно выполнять любые операции или вызовы методов и присваивать его любой переменной:
from typing import Any
a = None # type: Any
a = [] # ОК
a = 2 # ОК
s = '' # type: str
s = a # ОК
def foo(item: Any) -> int:
# Проходит проверку типов; 'item' может быть любого типа,
# и этот тип может иметь метод 'bar'
item.bar()
...
Обратите внимание, что никакая проверка типов не выполняется при присваивании значения типа Any более точному типу. Например, статический проверяющий типы не сообщил об ошибке при присваивании a переменной s, хотя s был объявлен как тип str и получает значение int во время выполнения!
Кроме того, все функции без указания типа возврата или типов параметров по умолчанию неявно используют Any:
def legacy_parser(text):
...
return data
# Статический проверщик типов будет рассматривать вышеприведенное
# как имеющее ту же сигнатуру, что и:
def legacy_parser(text: Any) -> Any:
...
return data
Такое поведение позволяет использовать Any в качестве запасного выхода, когда нужно смешивать динамически и статически типизированный код.
Сравните поведение Any с поведением object.
Как и Any, каждый тип является подтипом object. Однако,
в отличие от Any, обратное неверно: object не является
подтипом любого другого типа.
Это означает, что когда тип значения – object, проверяющий типы будет
отклонять почти все операции над ним, а присваивание его переменной (или использование
в качестве возвращаемого значения) более специализированного типа является ошибкой типа. Например:
def hash_a(item: object) -> int:
# Завершается ошибкой; у объекта нет метода 'magic'.
item.magic()
...
def hash_b(item: Any) -> int:
# Проходит проверку типов.
item.magic()
...
# Проходит проверку типов, так как int и str являются подклассами object.
hash_a(42)
hash_a("foo")
# Проходит проверку типов, так как Any совместим со всеми типами.
hash_b(42)
hash_b("foo")
Используйте object, чтобы указать, что значение может быть любого типа в типобезопасной
манере. Используйте Any, чтобы указать, что значение динамически типизировано.
Номинальная и структурная типизация¶Nominal vs structural subtyping
Изначально PEP 484 определял статическую систему типов Python как использующую номинальное подтипирование. Это означает, что класс A разрешён там, где ожидается класс B, только если A является подклассом B.
Ранее это требование также применялось к абстрактным базовым классам, таким как
Iterable. Проблема такого подхода в том, что класс должен
быть явно помечен для их поддержки, что непитонично и не похоже на то,
что обычно делается в идиоматическом динамически типизированном коде Python.
Например, следующее соответствует PEP 484:
from typing import Sized, Iterable, Iterator
class Bucket(Sized, Iterable[int]):
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
PEP 544 позволяет решить эту проблему, разрешая пользователям писать приведённый выше код без явных базовых классов в определении класса, что позволяет Bucket неявно считаться подтипом как Sized, так и Iterable[int] статическими проверяющими типов. Это называется структурной подтипизацией (или статической утиной типизацией):
from typing import Iterator, Iterable
class Bucket: # Примечание: базовые классы отсутствуют
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Проходит проверку типов
Более того, наследуя специальный класс Protocol, пользователь
может определять новые пользовательские протоколы, чтобы в полной мере использовать структурное подтипирование
(см. примеры ниже).
Классы, функции и декораторы¶Classes, functions, and decorators
Модуль определяет следующие классы, функции и декораторы:
-
class
typing.TypeVar¶ Переменная типа.
Использование:
T = TypeVar('T') # Может быть чем угодно A = TypeVar('A', str, bytes) # Должно быть str или bytes
Переменные типа существуют в первую очередь для статических анализаторов типов. Они служат параметрами для обобщённых типов, а также для определений обобщённых функций. См. класс Generic для получения дополнительной информации об обобщённых типах. Обобщённые функции работают следующим образом:
def repeat(x: T, n: int) -> Sequence[T]: """Возвращает список, содержащий n ссылок на x.""" return [x]*n def longest(x: A, y: A) -> A: """Возвращает самую длинную из двух строк.""" return x if len(x) >= len(y) else y
Сигнатура последнего примера по сути является перегрузкой
(str, str) -> strи(bytes, bytes) -> bytes. Также обратите внимание, что если аргументы являются экземплярами какого-либо подклассаstr, возвращаемый тип остаётся простымstr.Во время выполнения
isinstance(x, T)вызоветTypeError. В общем,isinstance()иissubclass()не должны использоваться с типами.Переменные типа могут быть помечены как ковариантные или контравариантные путём передачи
covariant=Trueилиcontravariant=True. См. PEP 484 для подробностей. По умолчанию переменные типа инвариантны. В качестве альтернативы, переменная типа может указывать верхнюю границу с помощьюbound=<type>. Это означает, что фактический тип, подставленный (явно или неявно) для переменной типа, должен быть подклассом граничного типа, см. PEP 484.
-
class
typing.Generic¶ Абстрактный базовый класс для обобщённых типов.
Обобщённый тип обычно объявляется наследованием от экземпляра этого класса с одной или несколькими переменными типа. Например, обобщённый тип отображения может быть определён так:
class Mapping(Generic[KT, VT]): def __getitem__(self, key: KT) -> VT: ... # И т.д.
Затем этот класс можно использовать следующим образом:
X = TypeVar('X') Y = TypeVar('Y') def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mapping[key] except KeyError: return default
-
class
typing.Protocol(Generic)¶ Базовый класс для классов протоколов. Классы протоколов определяются следующим образом:
class Proto(Protocol): def meth(self) -> int: ...
Такие классы в основном используются со статическими проверяющими типов, которые распознают структурную подтипизацию (статическую утиную типизацию), например:
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Проходит статическую проверку типов
Подробности см. в PEP 544. Классы протоколов, декорированные
runtime_checkable()(описаны далее), действуют как упрощённые протоколы времени выполнения, которые проверяют только наличие заданных атрибутов, игнорируя их сигнатуры типов.Протокольные классы могут быть обобщёнными, например:
class GenProto(Protocol[T]): def meth(self) -> T: ...
Новое в версии 3.8.
-
class
typing.Type(Generic[CT_co])¶ Переменная, аннотированная
C, может принимать значение типаC. Напротив, переменная, аннотированнаяType[C], может принимать значения, которые сами являются классами – а именно, она принимает объект классаC. Например:a = 3 # Имеет тип 'int' b = int # Имеет тип 'Type[int]' c = type(a) # Также имеет тип 'Type[int]'
Обратите внимание, что
Type[C]ковариантен:class User: ... class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ... # Принимает User, BasicUser, ProUser, TeamUser, ... def make_new_user(user_class: Type[User]) -> User: # ... return user_class()
Тот факт, что
Type[C]ковариантен, подразумевает, что все подклассыCдолжны реализовывать те же сигнатуры конструктора и методов класса, что иC. Средство проверки типов должно отмечать нарушения этого, но также должно разрешать вызовы конструкторов в подклассах, которые соответствуют вызовам конструктора в указанном базовом классе. То, как средство проверки типов должно обрабатывать этот конкретный случай, может измениться в будущих версиях PEP 484.Единственными допустимыми параметрами для
Typeявляются классы,Any, переменные типа и объединения любых из этих типов. Например:def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]): ...
Type[Any]эквивалентенType, который в свою очередь эквивалентенtype, корню метаклассовой иерархии Python.Новое в версии 3.5.2.
-
class
typing.Iterable(Generic[T_co])¶ Обобщённая версия
collections.abc.Iterable.
-
class
typing.Iterator(Iterable[T_co])¶ Обобщённая версия
collections.abc.Iterator.
-
class
typing.Reversible(Iterable[T_co])¶ Обобщённая версия
collections.abc.Reversible.
-
class
typing.SupportsInt¶ ABC с одним абстрактным методом
__int__.
-
class
typing.SupportsFloat¶ ABC с одним абстрактным методом
__float__.
-
class
typing.SupportsComplex¶ ABC с одним абстрактным методом
__complex__.
-
class
typing.SupportsBytes¶ ABC с одним абстрактным методом
__bytes__.
-
class
typing.SupportsIndex¶ ABC с одним абстрактным методом
__index__.Новое в версии 3.8.
-
class
typing.SupportsAbs¶ ABC с одним абстрактным методом
__abs__, ковариантным по типу возвращаемого значения.
-
class
typing.SupportsRound¶ ABC с одним абстрактным методом
__round__ковариантным по возвращаемому типу.
-
class
typing.Container(Generic[T_co])¶ Обобщённая версия
collections.abc.Container.
-
class
typing.Hashable¶ Псевдоним для
collections.abc.Hashable
-
class
typing.Sized¶ Псевдоним для
collections.abc.Sized
-
class
typing.Collection(Sized, Iterable[T_co], Container[T_co])¶ Обобщённая версия
collections.abc.CollectionНовое в версии 3.6.0.
-
class
typing.AbstractSet(Sized, Collection[T_co])¶ Обобщённая версия
collections.abc.Set.
-
class
typing.MutableSet(AbstractSet[T])¶ Обобщённая версия
collections.abc.MutableSet.
-
class
typing.Mapping(Sized, Collection[KT], Generic[VT_co])¶ Обобщённая версия
collections.abc.Mapping. Этот тип можно использовать следующим образом:def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: return word_list[word]
-
class
typing.MutableMapping(Mapping[KT, VT])¶ Обобщённая версия
collections.abc.MutableMapping.
-
class
typing.Sequence(Reversible[T_co], Collection[T_co])¶ Обобщённая версия
collections.abc.Sequence.
-
class
typing.MutableSequence(Sequence[T])¶ Обобщённая версия
collections.abc.MutableSequence.
-
class
typing.ByteString(Sequence[int])¶ Обобщённая версия
collections.abc.ByteString.Этот тип представляет типы
bytes,bytearrayиmemoryviewпоследовательностей байтов.В качестве сокращения для этого типа
bytesможно использовать для аннотации аргументов любого из упомянутых выше типов.
-
class
typing.Deque(deque, MutableSequence[T])¶ Обобщённая версия
collections.deque.Новое в версии 3.5.4.
Новое в версии 3.6.1.
-
class
typing.List(list, MutableSequence[T])¶ Обобщённая версия
list. Полезна для аннотирования возвращаемых типов. Для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, напримерSequenceилиIterable.Этот тип можно использовать следующим образом:
T = TypeVar('T', int, float) def vec2(x: T, y: T) -> List[T]: return [x, y] def keep_positives(vector: Sequence[T]) -> List[T]: return [item for item in vector if item > 0]
-
class
typing.Set(set, MutableSet[T])¶ Обобщённая версия
builtins.set. Полезна для аннотирования возвращаемых типов. Для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, напримерAbstractSet.
-
class
typing.FrozenSet(frozenset, AbstractSet[T_co])¶ Обобщённая версия
builtins.frozenset.
-
class
typing.MappingView(Sized, Iterable[T_co])¶ Обобщённая версия
collections.abc.MappingView.
-
class
typing.KeysView(MappingView[KT_co], AbstractSet[KT_co])¶ Обобщённая версия
collections.abc.KeysView.
-
class
typing.ItemsView(MappingView, Generic[KT_co, VT_co])¶ Обобщённая версия
collections.abc.ItemsView.
-
class
typing.ValuesView(MappingView[VT_co])¶ Обобщённая версия
collections.abc.ValuesView.
-
class
typing.Awaitable(Generic[T_co])¶ Обобщённая версия
collections.abc.Awaitable.Новое в версии 3.5.2.
-
class
typing.Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co])¶ Обобщённая версия
collections.abc.Coroutine. Вариантность и порядок переменных типа соответствуют таковым уGenerator, например:from typing import List, Coroutine c = None # type: Coroutine[List[str], str, int] ... x = c.send('hi') # type: List[str] async def bar() -> None: x = await c # type: int
Новое в версии 3.5.3.
-
class
typing.AsyncIterable(Generic[T_co])¶ Обобщённая версия
collections.abc.AsyncIterable.Новое в версии 3.5.2.
-
class
typing.AsyncIterator(AsyncIterable[T_co])¶ Обобщённая версия
collections.abc.AsyncIterator.Новое в версии 3.5.2.
-
class
typing.ContextManager(Generic[T_co])¶ Обобщённая версия
contextlib.AbstractContextManager.Новое в версии 3.5.4.
Новое в версии 3.6.0.
-
class
typing.AsyncContextManager(Generic[T_co])¶ Обобщённая версия
contextlib.AbstractAsyncContextManager.Новое в версии 3.5.4.
Новое в версии 3.6.2.
-
class
typing.Dict(dict, MutableMapping[KT, VT])¶ Обобщённая версия
dict. Полезна для аннотирования возвращаемых типов. Для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, напримерMapping.Этот тип можно использовать следующим образом:
def count_words(text: str) -> Dict[str, int]: ...
-
class
typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])¶ Обобщённая версия
collections.defaultdict.Новое в версии 3.5.2.
-
class
typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])¶ Обобщённая версия
collections.OrderedDict.Добавлено в версии 3.7.2.
-
class
typing.Counter(collections.Counter, Dict[T, int])¶ Обобщённая версия
collections.Counter.Новое в версии 3.5.4.
Новое в версии 3.6.1.
-
class
typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])¶ Обобщённая версия
collections.ChainMap.Новое в версии 3.5.4.
Новое в версии 3.6.1.
-
class
typing.Generator(Iterator[T_co], Generic[T_co, T_contra, V_co])¶ Генератор можно аннотировать обобщённым типом
Generator[YieldType, SendType, ReturnType]. Например:def echo_round() -> Generator[int, float, str]: sent = yield 0 while sent >= 0: sent = yield round(sent) return 'Done'
Обратите внимание: в отличие от многих других обобщённых типов в модуле typing,
SendTypeизGeneratorведёт себя контравариантно, а не ковариантно или инвариантно.Если ваш генератор будет только выдавать значения, установите
SendTypeиReturnTypeвNone:def infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1
В качестве альтернативы аннотируйте генератор как имеющий тип возвращаемого значения либо
Iterable[YieldType], либоIterator[YieldType]:def infinite_stream(start: int) -> Iterator[int]: while True: yield start start += 1
-
class
typing.AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra])¶ Асинхронный генератор можно аннотировать обобщённым типом
AsyncGenerator[YieldType, SendType]. Например:async def echo_round() -> AsyncGenerator[int, float]: sent = yield 0 while sent >= 0.0: rounded = await round(sent) sent = yield rounded
В отличие от обычных генераторов, асинхронные генераторы не могут возвращать значение, поэтому параметр типа
ReturnTypeотсутствует. Как и в случае сGenerator,SendTypeведёт себя контравариантно.Если генератор только выдаёт значения, установите
SendTypeвNone:async def infinite_stream(start: int) -> AsyncGenerator[int, None]: while True: yield start start = await increment(start)
В качестве альтернативы аннотируйте генератор как имеющий тип возвращаемого значения либо
AsyncIterable[YieldType], либоAsyncIterator[YieldType]:async def infinite_stream(start: int) -> AsyncIterator[int]: while True: yield start start = await increment(start)
Новое в версии 3.6.1.
-
class
typing.Text¶ Text– это псевдоним дляstr. Он предоставляется для обеспечения совместимости с кодом Python 2: в Python 2Textявляется псевдонимом дляunicode.Используйте
Text, чтобы указать, что значение должно содержать строку Unicode, совместимую как с Python 2, так и с Python 3:def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
Новое в версии 3.5.2.
-
class
typing.IO¶ -
class
typing.TextIO¶ -
class
typing.BinaryIO¶ Обобщённый тип
IO[AnyStr]и его подклассыTextIO(IO[str])иBinaryIO(IO[bytes])представляют типы потоков ввода-вывода, такие как возвращаемыеopen().
-
class
typing.Pattern¶ -
class
typing.Match¶ Эти псевдонимы типов соответствуют возвращаемым типам из
re.compile()иre.match(). Эти типы (и соответствующие функции) являются обобщёнными поAnyStrи могут быть конкретизированы записьюPattern[str],Pattern[bytes],Match[str]илиMatch[bytes].
-
class
typing.NamedTuple¶ Типизированная версия
collections.namedtuple().Использование:
class Employee(NamedTuple): name: str id: int
Это эквивалентно:
Employee = collections.namedtuple('Employee', ['name', 'id'])
Чтобы задать полю значение по умолчанию, можно присвоить его в теле класса:
class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') assert employee.id == 3
Поля со значением по умолчанию должны следовать после полей без значения по умолчанию.
Полученный класс имеет дополнительный атрибут
__annotations__, который возвращает словарь, сопоставляющий имена полей с их типами. (Имена полей находятся в атрибуте_fields, а значения по умолчанию – в атрибуте_field_defaults; оба являются частью API namedtuple.)Подклассы
NamedTupleтакже могут иметь докстринги и методы:class Employee(NamedTuple): """Представляет сотрудника.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'
Обратно совместимое использование:
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
Изменено в версии 3.6: Добавлена поддержка синтаксиса аннотации переменных PEP 526.
Изменено в версии 3.6.1: Добавлена поддержка значений по умолчанию, методов и строк документации.
Устарело с версии 3.8, будет удалено в версии 3.9: Устарел атрибут
_field_typesв пользу более стандартного атрибута__annotations__, который содержит ту же информацию.Изменено в версии 3.8: Атрибуты
_field_typesи__annotations__теперь являются обычными словарями, а не экземплярамиOrderedDict.
-
class
typing.TypedDict(dict)¶ Простое типизированное пространство имён. Во время выполнения оно эквивалентно обычному
dict.TypedDictсоздаёт тип словаря, который ожидает, что все его экземпляры будут иметь определённый набор ключей, где каждый ключ связан со значением единого типа. Это ожидание не проверяется во время выполнения, а обеспечивается только средствами проверки типов. Использование:class Point2D(TypedDict): x: int y: int label: str a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # ОК b: Point2D = {'z': 3, 'label': 'bad'} # Не проходит проверку типов assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
Информацию о типе для интроспекции можно получить через
Point2D.__annotations__иPoint2D.__total__. Чтобы обеспечить возможность использования этой возможности в старых версиях Python, не поддерживающих PEP 526,TypedDictподдерживает две дополнительные эквивалентные синтаксические формы:Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
По умолчанию в TypedDict должны присутствовать все ключи. Это можно переопределить, указав totality. Использование:
class point2D(TypedDict, total=False): x: int y: int
Это означает, что в TypedDict point2D любой из ключей может быть опущен. Средство проверки типов должно поддерживать только буквальные False или True в качестве значения аргумента total. Значение True используется по умолчанию и делает все элементы, определённые в теле класса, обязательными.
Смотрите PEP 589 для дополнительных примеров и подробных правил использования
TypedDict.Новое в версии 3.8.
-
class
typing.ForwardRef¶ Класс, используемый для внутреннего представления типов строковых прямых ссылок. Например,
List["SomeClass"]неявно преобразуется вList[ForwardRef("SomeClass")]. Этот класс не должен создаваться пользователем, но может использоваться инструментами интроспекции.Новое в версии 3.7.4.
-
typing.NewType(name, tp)¶ Вспомогательная функция для указания отдельного типа проверяющему типы, см. NewType. Во время выполнения она возвращает функцию, которая возвращает свой аргумент. Использование:
UserId = NewType('UserId', int) first_user = UserId(1)
Новое в версии 3.5.2.
-
typing.cast(typ, val)¶ Приводит значение к типу.
Это возвращает значение без изменений. Для проверщика типов это сигнализирует, что возвращаемое значение имеет указанный тип, но во время выполнения мы намеренно ничего не проверяем (мы хотим, чтобы это было как можно быстрее).
-
typing.get_type_hints(obj[, globals[, locals]])¶ Возвращает словарь, содержащий аннотации типов для функции, метода, модуля или объекта класса.
Это часто совпадает с
obj.__annotations__. Кроме того, прямые ссылки, закодированные как строковые литералы, обрабатываются путём вычисления их в пространствах имёнglobalsиlocals. При необходимостиOptional[t]добавляется для аннотаций функций и методов, если задано значение по умолчанию, равноеNone. Для классаCвозвращается словарь, построенный объединением всех__annotations__поC.__mro__в обратном порядке.
-
typing.get_origin(tp)¶
-
typing.get_args(tp)¶ Предоставляют базовую интроспекцию для обобщённых типов и специальных форм typing.
Для объекта typing вида
X[Y, Z, ...]эти функции возвращаютXи(Y, Z, ...). ЕслиXявляется обобщённым псевдонимом встроенного класса или классаcollections, он нормализуется до исходного класса. Для неподдерживаемых объектов возвращаютNoneи()соответственно. Примеры:assert get_origin(Dict[str, int]) is dict assert get_args(Dict[int, str]) == (int, str) assert get_origin(Union[int, str]) is Union assert get_args(Union[int, str]) == (int, str)
Новое в версии 3.8.
-
@typing.overload¶ Декоратор
@overloadпозволяет описывать функции и методы, поддерживающие несколько различных комбинаций типов аргументов. За серией определений, декорированных@overload, должно следовать ровно одно определение без@overload(для той же функции/метода). Определения с@overloadпредназначены только для проверки типов, так как они будут перезаписаны определением без@overload, которое используется во время выполнения, но должно игнорироваться проверщиком типов. Во время выполнения прямой вызов функции, декорированной@overload, вызоветNotImplementedError. Пример перегрузки, дающей более точный тип, чем можно выразить с помощью объединения или переменной типа:@overload def process(response: None) -> None: ... @overload def process(response: int) -> Tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): <actual implementation>
См. PEP 484 для подробностей и сравнения с другими семантиками типизации.
-
@typing.final¶ Декоратор, указывающий проверщикам типов, что декорированный метод нельзя переопределить, а декорированный класс нельзя наследовать. Например:
class Base: @final def done(self) -> None: ... class Sub(Base): def done(self) -> None: # Ошибка, выдаваемая проверщиком типов ... @final class Leaf: ... class Other(Leaf): # Ошибка, выдаваемая проверщиком типов ...
Проверка этих свойств во время выполнения не выполняется. Подробнее см. PEP 591.
Новое в версии 3.8.
-
@typing.no_type_check¶ Декоратор, указывающий, что аннотации не являются подсказками типов.
Это работает как декоратор класса или функции декоратор. В случае класса он рекурсивно применяется ко всем методам, определённым в этом классе (но не к методам, определённым в его суперклассах или подклассах).
Это изменяет функцию(и) на месте.
-
@typing.no_type_check_decorator¶ Декоратор, придающий другому декоратору эффект
no_type_check().Он оборачивает декоратор чем-то, что оборачивает декорированную функцию в
no_type_check().
-
@typing.type_check_only¶ Декоратор, помечающий класс или функцию как недоступные во время выполнения.
Сам этот декоратор недоступен во время выполнения. Он в основном предназначен для пометки классов, определённых в файлах заглушек типов (type stub), если реализация возвращает экземпляр закрытого класса:
@type_check_only class Response: # приватный или недоступный во время выполнения code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
Обратите внимание, что возврат экземпляров закрытых классов не рекомендуется. Обычно предпочтительнее делать такие классы открытыми.
-
@typing.runtime_checkable¶ Помечает протокольный класс как протокол времени выполнения.
Такой протокол может использоваться с
isinstance()иissubclass(). При применении к классу, не являющемуся протоколом, возникаетTypeError. Это позволяет выполнять простую структурную проверку, очень похожую на “one trick ponies” вcollections.abc, таких какIterable. Например:@runtime_checkable class Closable(Protocol): def close(self): ... assert isinstance(open('/some/file'), Closable)
Предупреждение: это проверяет только наличие необходимых методов, а не их сигнатуры типов!
Новое в версии 3.8.
-
typing.Any¶ Специальный тип, указывающий на неограниченный тип.
-
typing.NoReturn¶ Специальный тип, указывающий, что функция никогда не возвращает значение. Например:
from typing import NoReturn def stop() -> NoReturn: raise RuntimeError('no way')
Новое в версии 3.5.4.
Новое в версии 3.6.2.
-
typing.Union¶ Тип объединения;
Union[X, Y]означает либо X, либо Y.Чтобы определить объединение, используйте, например,
Union[int, str]. Подробности:Аргументы должны быть типами, и их должно быть как минимум один.
Объединения объединений разворачиваются, например:
Union[Union[int, str], float] == Union[int, str, float]
Объединения из одного аргумента исчезают, например:
Union[int] == int # Конструктор на самом деле возвращает int
Повторяющиеся аргументы пропускаются, например:
Union[int, str, int] == Union[int, str]
При сравнении объединений порядок аргументов игнорируется, например:
Union[int, str] == Union[str, int]
Нельзя создавать подкласс или экземпляр объединения.
Нельзя записать
Union[X][Y].Можно использовать
Optional[X]как сокращение дляUnion[X, None].
Изменено в версии 3.7: Явные подклассы не удаляются из объединений во время выполнения.
-
typing.Optional¶ Тип Optional.
Optional[X]эквивалентноUnion[X, None].Обратите внимание, что это не то же самое, что необязательный аргумент, который имеет значение по умолчанию. Необязательный аргумент с значением по умолчанию не требует квалификатора
Optionalв своей аннотации типа только потому, что он необязателен. Например:def foo(arg: int = 0) -> None: ...
С другой стороны, если явное значение
Noneдопускается, то использованиеOptionalуместно, независимо от того, является ли аргумент необязательным или нет. Например:def foo(arg: Optional[int] = None) -> None: ...
-
typing.Tuple¶ Тип кортежа;
Tuple[X, Y]– это тип кортежа из двух элементов, где первый элемент имеет тип X, а второй – Y. Тип пустого кортежа может быть записан какTuple[()].Пример:
Tuple[T1, T2]– это кортеж из двух элементов, соответствующих переменным типа T1 и T2.Tuple[int, float, str]– это кортеж из int, float и строки.Чтобы задать кортеж переменной длины из однотипных элементов, используйте литеральное многоточие, например
Tuple[int, ...]. ПростойTupleэквивалентенTuple[Any, ...], а тот, в свою очередь,tuple.
-
typing.Callable¶ Тип Callable;
Callable[[int], str]– это функция вида (int) -> str.Синтаксис индексирования всегда должен использоваться ровно с двумя значениями: списком аргументов и типом возвращаемого значения. Список аргументов должен быть списком типов или многоточием; тип возвращаемого значения должен быть одним типом.
Нет синтаксиса для указания необязательных или именованных аргументов; такие типы функций редко используются в качестве типов колбэков.
Callable[..., ReturnType](буквальное многоточие) можно использовать для аннотации вызываемого объекта, принимающего любое количество аргументов и возвращающегоReturnType. ОбычноеCallableэквивалентноCallable[..., Any], а в свою очередь –collections.abc.Callable.
-
typing.Literal¶ Тип, который можно использовать для указания средствам проверки типов, что соответствующая переменная или параметр функции имеет значение, эквивалентное предоставленному литералу (или одному из нескольких литералов). Например:
def validate_simple(data: Any) -> Literal[True]: # всегда возвращает True ... MODE = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: MODE) -> str: ... open_helper('/some/path', 'r') # Проходит проверку типов open_helper('/other/path', 'typo') # Ошибка в тайпчекере
Literal[...]нельзя наследовать. Во время выполнения произвольное значение допускается в качестве аргумента типа дляLiteral[...], но проверяющие типа могут накладывать ограничения. См. PEP 586 для получения дополнительных сведений о литеральных типах.Новое в версии 3.8.
-
typing.ClassVar¶ Специальная конструкция типа для пометки переменных класса.
Как представлено в PEP 526, аннотация переменной, обёрнутая в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен устанавливаться на экземплярах этого класса. Использование:
class Starship: stats: ClassVar[Dict[str, int]] = {} # переменная класса damage: int = 10 # переменная экземпляра
ClassVarпринимает только типы и не может быть дополнительно индексирован.ClassVarсам по себе не является классом и не должен использоваться сisinstance()илиissubclass().ClassVarне меняет поведение Python во время выполнения, но может использоваться сторонними проверяющими типов. Например, проверяющий типов может отметить следующий код как ошибочный:enterprise_d = Starship(3000) enterprise_d.stats = {} # Ошибка: установка переменной класса на экземпляре Starship.stats = {} # Это корректно.
Новое в версии 3.5.3.
-
typing.Final¶ Специальная конструкция типов для указания средствам проверки типов, что имя не может быть переприсвоено или переопределено в подклассе. Например:
MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Ошибка, выдаваемая проверщиком типов class Connection: TIMEOUT: Final[int] = 10 class FastConnector(Connection): TIMEOUT = 1 # Ошибка, выдаваемая проверщиком типов
Проверка этих свойств во время выполнения не выполняется. Подробнее см. PEP 591.
Новое в версии 3.8.
-
typing.AnyStr¶ AnyStr– это переменная типа, определённая какAnyStr = TypeVar('AnyStr', str, bytes).Предназначен для функций, которые могут принимать строки любого типа, не допуская смешивания разных типов строк. Например:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat(u"foo", u"bar") # Ок, результат имеет тип 'unicode' concat(b"foo", b"bar") # Ок, результат имеет тип 'bytes' concat(u"foo", b"bar") # Ошибка, нельзя смешивать unicode и bytes
-
typing.TYPE_CHECKING¶ Специальная константа, которая считается
Trueсторонними статическими проверщиками типов. Во время выполнения она равнаFalse. Применение:if TYPE_CHECKING: import expensive_mod def fun(arg: 'expensive_mod.SomeType') -> None: local_var: expensive_mod.AnotherType = other_fun()
Обратите внимание, что первая аннотация типа должна быть заключена в кавычки, что делает её «отложенной ссылкой» (forward reference), чтобы скрыть ссылку
expensive_modот интерпретатора во время выполнения. Аннотации типов для локальных переменных не вычисляются, поэтому вторую аннотацию заключать в кавычки не нужно.Новое в версии 3.5.2.