typing
— Поддержка подсказок типов¶
Добавлено в версии 3.5.
Исходный код: Lib/typing.py.
Примечание
Время выполнения Python не обеспечивает аннотации типов функций и переменных. Они могут использоваться сторонними инструментами, такими как программы проверки типов, IDE, линтеры и т.д.
Этот модуль обеспечивает поддержку во время выполнения подсказок типов. Наиболее фундаментальная поддержка состоит из типов Any
, Union
, Callable
, TypeVar
и Generic
. Полная спецификация приведена в разделе PEP 484. Упрощенное введение в подсказки типов см. в PEP 483.
Приведенная ниже функция принимает и возвращает строку и аннотирована следующим образом:
def greeting(name: str) -> str:
return 'Hello ' + name
В функции greeting
ожидается, что аргумент name
будет иметь тип str
, а возвращаемый тип str
. В качестве аргументов принимаются подтипы.
В модуль typing
часто добавляются новые возможности. Пакет typing_extensions предоставляет обратные переносы этих новых возможностей в старые версии Python.
Соответствующие ПЭП¶
С момента первоначального внедрения подсказок типов в PEP 484 и PEP 483, ряд PEP изменил и улучшил структуру Python для аннотаций типов. К ним относятся:
- PEP 544: Протоколы: Структурная подтипизация (статическая утиная типизация)
Введение
Protocol
и декоратора@runtime_checkable
- PEP 585: Generics с подсказкой типа в стандартных коллекциях
Введение
types.GenericAlias
и возможность использования классов стандартной библиотеки в качестве generic types.
- PEP 604: Разрешить запись типов объединений как
X | Y
Введение
types.UnionType
и возможность использования оператора бинарного или|
для обозначения union of types
- PEP 604: Разрешить запись типов объединений как
- PEP 612: Переменные спецификации параметров
Введение
ParamSpec
иConcatenate
Псевдонимы типов¶
Псевдоним типа определяется путем присвоения типа псевдониму. В данном примере Vector
и list[float]
будут рассматриваться как взаимозаменяемые синонимы:
Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
Псевдонимы типов полезны для упрощения сложных сигнатур типов. Например:
from collections.abc import Sequence
ConnectionOptions = dict[str, str]
Address = tuple[str, int]
Server = tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None:
...
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
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:
...
# typechecks
user_a = get_user_name(UserId(42351))
# does not typecheck; an int is not a UserId
user_b = get_user_name(-1)
Вы можете по-прежнему выполнять все операции int
над переменной типа UserId
, но результат всегда будет иметь тип int
. Это позволяет передавать переменную UserId
везде, где можно ожидать int
, но предотвращает случайное создание UserId
недопустимым способом:
# 'output' is of type 'int', not '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)
# Fails at runtime and does not typecheck
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.
Изменено в версии 3.10: NewType
теперь является классом, а не функцией. Существуют некоторые дополнительные затраты времени выполнения при вызове NewType
вместо обычной функции. Однако в версии 3.11.0 эти затраты будут снижены.
С правом выкупа¶
Фреймворки, ожидающие функции обратного вызова с определенными сигнатурами, могут иметь подсказку типа с помощью Callable[[Arg1Type, Arg2Type], ReturnType]
.
Например:
from collections.abc import Callable
def feeder(get_next_item: Callable[[], str]) -> None:
# Body
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
# Body
async def on_update(value: str) -> None:
# Body
callback: Callable[[str], Awaitable[None]] = on_update
Можно объявить тип возврата вызываемого объекта без указания сигнатуры вызова, заменив список аргументов в подсказке типа буквенным многоточием: Callable[..., ReturnType]
.
Вызываемые модули, которые принимают в качестве аргументов другие вызываемые модули, могут указать, что их типы параметров зависят друг от друга, используя оператор ParamSpec
. Кроме того, если эта вызываемая переменная добавляет или удаляет аргументы из других вызываемых переменных, можно использовать оператор Concatenate
. Они принимают форму Callable[ParamSpecVariable, ReturnType]
и Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType]
соответственно.
Изменено в версии 3.10: Callable
теперь поддерживает ParamSpec
и Concatenate
. Дополнительную информацию см. в разделе PEP 612.
См.также
В документации к ParamSpec
и Concatenate
приведены примеры использования в Callable
.
Дженерики¶
Поскольку информация о типах объектов, хранящихся в контейнерах, не может быть статически выведена общим способом, абстрактные базовые классы были расширены для поддержки подписки для обозначения ожидаемых типов для элементов контейнера.
from collections.abc import Mapping, Sequence
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
Генерики могут быть параметризованы с помощью фабрики, доступной в типизации под названием TypeVar
.
from collections.abc import Sequence
from typing import TypeVar
T = TypeVar('T') # Declare type variable
def first(l: Sequence[T]) -> T: # Generic function
return l[0]
Определяемые пользователем общие типы¶
Определяемый пользователем класс может быть определен как общий класс.
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 collections.abc import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
Родовой тип может иметь любое количество переменных типа. Все разновидности TypeVar
допустимы в качестве параметров для общего типа:
from typing import TypeVar, Generic, Sequence
T = TypeVar('T', contravariant=True)
B = TypeVar('B', bound=Sequence[bytes], covariant=True)
S = TypeVar('S', int, str)
class WeirdTrio(Generic[T, B, S]):
...
Каждый аргумент переменной типа в Generic
должен быть отдельным. Таким образом, это недействительно:
from typing import TypeVar, Generic
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
Вы можете использовать множественное наследование с помощью Generic
:
from collections.abc import Sized
from typing import TypeVar, Generic
T = TypeVar('T')
class LinkedList(Sized, Generic[T]):
...
При наследовании от общих классов некоторые переменные типа могут быть исправлены:
from collections.abc import Mapping
from typing import TypeVar
T = TypeVar('T')
class MyDict(Mapping[str, T]):
...
В данном случае MyDict
имеет один параметр, T
.
Использование родового класса без указания параметров типа предполагает Any
для каждой позиции. В следующем примере MyIterable
не является родовым, но неявно наследуется от Iterable[Any]
:
from collections.abc import Iterable
class MyIterable(Iterable): # Same as Iterable[Any]
Также поддерживаются псевдонимы общих типов, определяемые пользователем. Примеры:
from collections.abc import Iterable
from typing import TypeVar
S = TypeVar('S')
Response = Iterable[S] | int
# Return type here is same as 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: # Same as Iterable[tuple[T, T]]
return sum(x*y for x, y in v)
Изменено в версии 3.7: Generic
больше не имеет пользовательского метакласса.
Определяемые пользователем дженерики для выражений параметров также поддерживаются через переменные спецификации параметров в форме Generic[P]
. Поведение соответствует описанному выше поведению переменных типов, поскольку переменные спецификации параметров рассматриваются модулем типизации как специализированные переменные типов. Единственным исключением является то, что список типов может быть использован для замены ParamSpec
:
>>> from typing import Generic, ParamSpec, TypeVar
>>> T = TypeVar('T')
>>> P = ParamSpec('P')
>>> class Z(Generic[T, P]): ...
...
>>> Z[int, [dict, float]]
__main__.Z[int, (<class 'dict'>, <class 'float'>)]
Более того, дженерик с одной переменной спецификации параметров будет принимать списки параметров в форме X[[Type1, Type2, ...]]
, а также X[Type1, Type2, ...]
из эстетических соображений. Внутренне последняя форма преобразуется в первую, поэтому следующие формы эквивалентны:
>>> class X(Generic[P]): ...
...
>>> X[int, str]
__main__.X[(<class 'int'>, <class 'str'>)]
>>> X[[int, str]]
__main__.X[(<class 'int'>, <class 'str'>)]
Обратите внимание, что дженерики с ParamSpec
в некоторых случаях могут не иметь корректных __parameters__
после подстановки, поскольку они предназначены в первую очередь для статической проверки типов.
Изменено в версии 3.10: Generic
теперь можно параметризовать через выражения параметров. Более подробную информацию смотрите в ParamSpec
и PEP 612.
Определяемый пользователем общий класс может иметь ABC в качестве базовых классов без конфликта с метаклассами. Родовые метаклассы не поддерживаются. Результат параметризации родовых классов кэшируется, а большинство типов в модуле типизации хэшируются и сравниваются на равенство.
Тип Any
¶
Особым видом типа является Any
. Статическая программа проверки типов будет рассматривать каждый тип как совместимый с Any
, а Any
- как совместимый с любым типом.
Это означает, что можно выполнить любую операцию или вызов метода над значением типа Any
и присвоить его любой переменной:
from typing import Any
a: Any = None
a = [] # OK
a = 2 # OK
s: str = ''
s = a # OK
def foo(item: Any) -> int:
# Typechecks; 'item' could be any type,
# and that type might have a 'bar' method
item.bar()
...
Обратите внимание, что при присвоении значения типа Any
более точному типу проверка типов не выполняется. Например, статическая проверка типов не сообщила об ошибке при присвоении a
в s
, даже если s
было объявлено как тип str
и во время выполнения получает значение int
!
Более того, все функции без возвращаемого типа или типов параметров будут неявно по умолчанию использовать Any
:
def legacy_parser(text):
...
return data
# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
...
return data
Такое поведение позволяет использовать Any
в качестве эскейп-люка, когда вам нужно смешать динамически и статически типизированный код.
Противопоставьте поведение Any
поведению object
. Подобно Any
, каждый тип является подтипом object
. Однако, в отличие от Any
, обратное не верно: object
является не подтипом любого другого типа.
Это означает, что если тип значения object
, программа проверки типов отклонит почти все операции над ним, а присвоение его переменной (или использование его в качестве возвращаемого значения) более специализированного типа будет ошибкой типа. Например:
def hash_a(item: object) -> int:
# Fails; an object does not have a 'magic' method.
item.magic()
...
def hash_b(item: Any) -> int:
# Typechecks
item.magic()
...
# Typechecks, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")
# Typechecks, since Any is compatible with all types
hash_b(42)
hash_b("foo")
Используйте object
, чтобы указать, что значение может быть любого типа безопасным для типов образом. Используйте Any
, чтобы указать, что значение динамически типизировано.
Номинальная и структурная подтипизация¶
Первоначально PEP 484 определил статическую систему типов Python как использующую номинальную подтипизацию. Это означает, что класс A
допускается там, где ожидается класс B
, если и только если A
является подклассом B
.
Ранее это требование распространялось и на абстрактные базовые классы, такие как Iterable
. Проблема такого подхода заключалась в том, что класс должен был быть явно помечен для их поддержки, что непитонично и не похоже на то, что обычно делается в идиоматическом динамически типизированном коде Python. Например, это соответствует PEP 484:
from collections.abc 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 collections.abc import Iterator, Iterable
class Bucket: # Note: no base classes
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Passes type check
Более того, создав подкласс специального класса Protocol
, пользователь может определить новые пользовательские протоколы, чтобы в полной мере использовать структурную подтипизацию (см. примеры ниже).
Содержание модуля¶
В модуле определены следующие классы, функции и декораторы.
Примечание
Этот модуль определяет несколько типов, которые являются подклассами ранее существовавших классов стандартной библиотеки, которые также расширяют Generic
для поддержки переменных типа внутри []
. Эти типы стали излишними в Python 3.9, когда соответствующие ранее существовавшие классы были расширены для поддержки []
.
Избыточные типы устарели по сравнению с Python 3.9, но интерпретатор не будет выдавать предупреждений об устаревании. Ожидается, что программы проверки типов будут отмечать устаревшие типы, если проверяемая программа использует Python 3.9 или более новую версию.
Устаревшие типы будут удалены из модуля typing
в первой версии Python, выпущенной через 5 лет после выхода Python 3.9.0. Подробности см. в PEP 585-Типовая подсказка Generics In Standard Collections.
Специальные примитивы типизации¶
Специальные типы¶
Они могут использоваться как типы в аннотациях и не поддерживают []
.
-
typing.
Any
¶ Специальный тип, указывающий на неограниченный тип.
-
typing.
NoReturn
¶ Специальный тип, указывающий на то, что функция никогда не возвращается. Например:
from typing import NoReturn def stop() -> NoReturn: raise RuntimeError('no way')
Добавлено в версии 3.5.4.
Добавлено в версии 3.6.2.
-
typing.
TypeAlias
¶ Специальная аннотация для явного объявления type alias. Например:
from typing import TypeAlias Factors: TypeAlias = list[int]
Более подробную информацию о явных псевдонимах типов смотрите в PEP 613.
Добавлено в версии 3.10.
Специальные формы¶
Их можно использовать в качестве типов в аннотациях с помощью []
, каждый из которых имеет уникальный синтаксис.
-
typing.
Tuple
¶ Тип кортежа;
Tuple[X, Y]
- тип кортежа из двух элементов, первый элемент которого имеет тип X, а второй - тип Y. Тип пустого кортежа можно записать какTuple[()]
.Пример:
Tuple[T1, T2]
- это кортеж из двух элементов, соответствующих переменным типа T1 и T2.Tuple[int, float, str]
- это кортеж из int, float и string.Чтобы указать кортеж переменной длины однородного типа, используйте литеральное многоточие, например,
Tuple[int, ...]
. ОбычныйTuple
эквивалентенTuple[Any, ...]
, а тот, в свою очередь,tuple
.Не рекомендуется, начиная с версии 3.9:
builtins.tuple
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
typing.
Union
¶ Тип союза;
Union[X, Y]
эквивалентенX | Y
и означает либо X, либо Y.Для определения объединения используйте, например,
Union[int, str]
или сокращениеint | str
. Рекомендуется использовать это сокращение. Подробности:Аргументы должны быть типами, и их должно быть не менее одного.
Союзы союзов уплощаются, например:
Union[Union[int, str], float] == Union[int, str, float]
Союзы одного аргумента исчезают, например:
Union[int] == int # The constructor actually returns int
Лишние аргументы пропускаются, например:
Union[int, str, int] == Union[int, str] == int | str
При сравнении союзов порядок аргументов игнорируется, например:
Union[int, str] == Union[str, int]
Вы не можете подклассифицировать или инстанцировать
Union
.Вы не можете написать
Union[X][Y]
.
Изменено в версии 3.7: Не удаляйте явные подклассы из союзов во время выполнения.
Изменено в версии 3.10: Союзы теперь можно записывать как
X | Y
. См. union type expressions.
-
typing.
Optional
¶ Дополнительный тип.
Optional[X]
эквивалентенX | None
(илиUnion[X, None]
).Обратите внимание, что это не то же самое понятие, что опциональный аргумент, который имеет значение по умолчанию. Необязательный аргумент, имеющий значение по умолчанию, не требует наличия квалификатора
Optional
в аннотации типа только потому, что он является необязательным. Например:def foo(arg: int = 0) -> None: ...
С другой стороны, если допускается явное значение
None
, то использованиеOptional
уместно, независимо от того, является ли аргумент необязательным или нет. Например:def foo(arg: Optional[int] = None) -> None: ...
Изменено в версии 3.10: Optional теперь можно записать как
X | None
. См. union type expressions.
-
typing.
Callable
¶ Вызываемый тип;
Callable[[int], str]
является функцией (int) -> str.Синтаксис подписки всегда должен использоваться ровно с двумя значениями: списком аргументов и возвращаемым типом. Список аргументов должен быть списком типов или многоточием; возвращаемый тип должен быть одним типом.
Синтаксис для указания необязательных или ключевых аргументов отсутствует; такие типы функций редко используются в качестве типов обратного вызова.
Callable[..., ReturnType]
(литеральное многоточие) может использоваться для указания на вызываемую функцию, принимающую любое количество аргументов и возвращающуюReturnType
. ОбычныйCallable
эквивалентенCallable[..., Any]
, а тот в свою очередьcollections.abc.Callable
.Вызываемые модули, которые принимают в качестве аргументов другие вызываемые модули, могут указать, что их типы параметров зависят друг от друга, используя оператор
ParamSpec
. Кроме того, если эта вызываемая переменная добавляет или удаляет аргументы из других вызываемых переменных, можно использовать операторConcatenate
. Они принимают формуCallable[ParamSpecVariable, ReturnType]
иCallable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType]
соответственно.Не рекомендуется, начиная с версии 3.9:
collections.abc.Callable
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.Изменено в версии 3.10:
Callable
теперь поддерживаетParamSpec
иConcatenate
. Дополнительную информацию см. в разделе PEP 612.См.также
В документации к
ParamSpec
иConcatenate
приведены примеры использования сCallable
.
-
typing.
Concatenate
¶ Используется вместе с
Callable
иParamSpec
для аннотирования типа вызываемой переменной более высокого порядка, которая добавляет, удаляет или преобразует параметры другой вызываемой переменной. Используется в формеConcatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]
.Concatenate
в настоящее время действителен только при использовании в качестве первого аргументаCallable
. Последний параметрConcatenate
должен бытьParamSpec
.Например, для аннотации декоратора
with_lock
, который предоставляетthreading.Lock
декорируемой функции,Concatenate
можно использовать для указания того, чтоwith_lock
ожидает callable, который принимаетLock
в качестве первого аргумента, а возвращает callable с другой сигнатурой типа. В этом случаеParamSpec
указывает, что типы параметров возвращаемой вызываемой переменной зависят от типов параметров передаваемой вызываемой переменной:from collections.abc import Callable from threading import Lock from typing import Concatenate, ParamSpec, TypeVar P = ParamSpec('P') R = TypeVar('R') # Use this lock to ensure that only one thread is executing a function # at any time. my_lock = Lock() def with_lock(f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''A type-safe decorator which provides a lock.''' def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. return f(my_lock, *args, **kwargs) return inner @with_lock def sum_threadsafe(lock: Lock, numbers: list[float]) -> float: '''Add a list of numbers together in a thread-safe manner.''' with lock: return sum(numbers) # We don't need to pass in the lock ourselves thanks to the decorator. sum_threadsafe([1.1, 2.2, 3.3])
Добавлено в версии 3.10.
См.также
-
class
typing.
Type
(Generic[CT_co])¶ Переменная, аннотированная
C
, может принимать значение типаC
. Напротив, переменная, аннотированнаяType[C]
, может принимать значения, которые сами являются классами - в частности, она будет принимать класс-объектC
. Например:a = 3 # Has type 'int' b = int # Has type 'Type[int]' c = type(a) # Also has type 'Type[int]'
Обратите внимание, что
Type[C]
является ковариантным:class User: ... class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ... # Accepts User, BasicUser, ProUser, TeamUser, ... def make_new_user(user_class: Type[User]) -> User: # ... return user_class()
Тот факт, что
Type[C]
является ковариантным, подразумевает, что все подклассыC
должны реализовывать те же сигнатуры конструкторов и сигнатуры методов класса, что иC
. Программа проверки типов должна отмечать нарушения этого, но также должна разрешать вызовы конструкторов в подклассах, которые соответствуют вызовам конструкторов в указанном базовом классе. То, как программа проверки типов должна обрабатывать этот конкретный случай, может измениться в будущих редакциях PEP 484.Единственными законными параметрами для
Type
являются классы,Any
, type variables и объединения любого из этих типов. Например:def new_non_team_user(user_class: Type[BasicUser | ProUser]): ...
Type[Any]
эквивалентенType
, который в свою очередь эквивалентенtype
, что является корнем иерархии метаклассов Python.Добавлено в версии 3.5.2.
Не рекомендуется, начиная с версии 3.9:
builtins.type
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
typing.
Literal
¶ Тип, который может использоваться для указания средствам проверки типов, что соответствующая переменная или параметр функции имеет значение, эквивалентное предоставленному литералу (или одному из нескольких литералов). Например:
def validate_simple(data: Any) -> Literal[True]: # always returns True ... MODE = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: MODE) -> str: ... open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checker
Literal[...]
не может быть подклассом. Во время выполнения в качестве аргумента типа вLiteral[...]
допускается произвольное значение, но программы проверки типов могут накладывать ограничения. Более подробную информацию о литеральных типах смотрите в PEP 586.Добавлено в версии 3.8.
-
typing.
ClassVar
¶ Конструкция специального типа для маркировки переменных класса.
Как было введено в PEP 526, аннотация переменной, обернутая в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен быть установлен на экземплярах этого класса. Использование:
class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable
ClassVar
принимает только типы и не может быть дополнительно подписан.ClassVar
сам по себе не является классом и не должен использоваться сisinstance()
илиissubclass()
.ClassVar
не изменяет поведение во время выполнения Python, но может использоваться сторонними программами проверки типов. Например, программа проверки типов может отметить следующий код как ошибку:enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OK
Добавлено в версии 3.5.3.
-
typing.
Final
¶ Специальная конструкция типизации, указывающая средствам проверки типов, что имя не может быть переназначено или переопределено в подклассе. Например:
MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Error reported by type checker class Connection: TIMEOUT: Final[int] = 10 class FastConnector(Connection): TIMEOUT = 1 # Error reported by type checker
Проверка этих свойств во время выполнения не предусмотрена. Более подробную информацию см. в разделе PEP 591.
Добавлено в версии 3.8.
-
typing.
Annotated
¶ Тип, введенный в PEP 593 (
Flexible function and variable annotations
), для украшения существующих типов контекстно-зависимыми метаданными (возможно, несколькими частями, посколькуAnnotated
является переменным). В частности, типT
может быть аннотирован метаданнымиx
через typehintAnnotated[T, x]
. Эти метаданные могут быть использованы как для статического анализа, так и во время выполнения. Если библиотека (или инструмент) встречает typehintAnnotated[T, x]
и не имеет специальной логики для метаданныхx
, она должна игнорировать его и просто рассматривать тип какT
. В отличие от функциональностиno_type_check
, существующей в модулеtyping
, которая полностью отключает аннотации проверки типов для функции или класса, типAnnotated
позволяет как статическую проверку типовT
(которая может безопасно игнорироватьx
), так и доступ кx
в рамках конкретного приложения.В конечном счете, ответственность за то, как интерпретировать аннотации (если это вообще возможно), лежит на инструменте или библиотеке, столкнувшейся с типом
Annotated
. Инструмент или библиотека, встретив типAnnotated
, может просмотреть аннотации, чтобы определить, представляют ли они интерес (например, используяisinstance()
).Если инструмент или библиотека не поддерживает аннотации или встречает неизвестную аннотацию, он должен просто игнорировать ее и рассматривать аннотированный тип как базовый тип.
Инструмент, потребляющий аннотации, должен решить, разрешено ли клиенту иметь несколько аннотаций на один тип и как объединить эти аннотации.
Поскольку тип
Annotated
позволяет вам поместить несколько аннотаций одного (или разных) типа на любой узел, инструменты или библиотеки, потребляющие эти аннотации, отвечают за работу с потенциальными дубликатами. Например, если вы проводите анализ диапазона значений, вы можете разрешить следующее:T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)]
Передача
include_extras=True
вget_type_hints()
позволяет получить доступ к дополнительным аннотациям во время выполнения.Детали синтаксиса:
Первый аргумент
Annotated
должен быть допустимым типомПоддерживаются аннотации нескольких типов (
Annotated
поддерживает переменные аргументы):Annotated[int, ValueRange(3, 10), ctype("char")]
Annotated
должен вызываться как минимум с двумя аргументами (Annotated[int]
недействителен)Порядок аннотаций сохраняется и имеет значение для проверки равенства:
Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ int, ctype("char"), ValueRange(3, 10) ]
Вложенные типы
Annotated
уплощаются, метаданные упорядочиваются, начиная с самой внутренней аннотации:Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ int, ValueRange(3, 10), ctype("char") ]
Дублирующие аннотации не удаляются:
Annotated[int, ValueRange(3, 10)] != Annotated[ int, ValueRange(3, 10), ValueRange(3, 10) ]
Annotated
можно использовать с вложенными и общими псевдонимами:T = TypeVar('T') Vec = Annotated[list[tuple[T, T]], MaxLen(10)] V = Vec[int] V == Annotated[list[tuple[int, int]], MaxLen(10)]
Добавлено в версии 3.9.
-
typing.
TypeGuard
¶ Специальная форма типизации, используемая для аннотации возвращаемого типа пользовательской функции защиты типа.
TypeGuard
принимает только один аргумент типа. Во время выполнения функции, помеченные таким образом, должны возвращать булево значение.TypeGuard
нацелен на пользу сужения типа - техники, используемой статическими программами проверки типов для определения более точного типа выражения в потоке кода программы. Обычно сужение типа выполняется путем анализа условного потока кода и применения сужения к блоку кода. Условное выражение здесь иногда называют «защитой типа»:def is_str(val: str | float): # "isinstance" type guard if isinstance(val, str): # Type of ``val`` is narrowed to ``str`` ... else: # Else, type of ``val`` is narrowed to ``float``. ...
Иногда удобно использовать определяемую пользователем функцию boolean в качестве защиты типа. Такая функция должна использовать
TypeGuard[...]
в качестве возвращаемого типа, чтобы предупредить статические средства проверки типов об этом намерении.Использование
-> TypeGuard
сообщает статической программе проверки типов, что для данной функции:Возвращаемое значение - булево значение.
Если возвращаемое значение
True
, то типом его аргумента является тип внутриTypeGuard
.
Например:
def is_str_list(val: List[object]) -> TypeGuard[List[str]]: '''Determines whether all objects in the list are strings''' return all(isinstance(x, str) for x in val) def func1(val: List[object]): if is_str_list(val): # Type of ``val`` is narrowed to ``List[str]``. print(" ".join(val)) else: # Type of ``val`` remains as ``List[object]``. print("Not a list of strings!")
Если
is_str_list
является методом класса или экземпляра, то тип вTypeGuard
отображается на тип второго параметра послеcls
илиself
.Вкратце, форма
def foo(arg: TypeA) -> TypeGuard[TypeB]: ...
означает, что еслиfoo(arg)
возвращаетTrue
, тоarg
сужается отTypeA
доTypeB
.Примечание
TypeB
не обязательно должен быть более узкой формойTypeA
- он может быть даже более широкой формой. Основная причина заключается в том, чтобы позволить такие вещи, как сужениеList[object]
доList[str]
, даже если последний не является подтипом первого, посколькуList
является инвариантным. Ответственность за написание безопасных для типов защит типов возлагается на пользователя.TypeGuard
также работает с переменными типа. Для получения дополнительной информации смотрите PEP 647 (Охрана типов, определяемых пользователем).Добавлено в версии 3.10.
Построение общих типов¶
Они не используются в аннотациях. Они являются строительными блоками для создания общих типов.
-
class
typing.
Generic
¶ Абстрактный базовый класс для общих типов.
Общий тип обычно объявляется путем наследования от инстанса этого класса с одной или несколькими переменными типа. Например, общий тип отображения может быть определен как:
class Mapping(Generic[KT, VT]): def __getitem__(self, key: KT) -> VT: ... # Etc.
Этот класс можно использовать следующим образом:
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.
TypeVar
¶ Тип переменной.
Использование:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Переменные типа существуют в основном для пользы статических средств проверки типов. Они служат параметрами для родовых типов, а также для определений родовых функций. Более подробную информацию о родовых типах смотрите в
Generic
. Родовые функции работают следующим образом:def repeat(x: T, n: int) -> Sequence[T]: """Return a list containing n references to x.""" return [x]*n def print_capitalized(x: S) -> S: """Print x capitalized, and return x.""" print(x.capitalize()) return x def concatenate(x: A, y: A) -> A: """Add two strings or bytes objects together.""" return x + y
Обратите внимание, что переменные типа могут быть связанными, ограниченными или ни теми, ни другими, но не могут быть одновременно связанными и ограниченными.
Ограниченные переменные типа и связанные переменные типа имеют разную семантику в нескольких важных аспектах. Использование ограниченной переменной типа означает, что переменная
TypeVar
может быть решена только как являющаяся в точности одним из заданных ограничений:a = concatenate('one', 'two') # Ok, variable 'a' has type 'str' b = concatenate(StringSubclass('one'), StringSubclass('two')) # Inferred type of variable 'b' is 'str', # despite 'StringSubclass' being passed in c = concatenate('one', b'two') # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both
Использование связанной переменной типа, однако, означает, что
TypeVar
будет решаться с использованием наиболее конкретного типа из возможных:print_capitalized('a string') # Ok, output has type 'str' class StringSubclass(str): pass print_capitalized(StringSubclass('another string')) # Ok, output has type 'StringSubclass' print_capitalized(45) # error: int is not a subtype of str
Переменные типа могут быть связаны с конкретными типами, абстрактными типами (ABC или протоколами) и даже с объединениями типов:
U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
Связанные переменные типа особенно полезны для аннотирования
classmethods
, которые служат альтернативными конструкторами. В следующем примере (на Raymond Hettinger) переменная типаC
привязана к классуCircle
с помощью прямой ссылки. Использование этой переменной типа для аннотирования метода классаwith_circumference
, а не жесткое кодирование возвращаемого типа какCircle
, означает, что программа проверки типов может правильно определить возвращаемый тип, даже если метод вызывается в подклассе:import math C = TypeVar('C', bound='Circle') class Circle: """An abstract circle""" def __init__(self, radius: float) -> None: self.radius = radius # Use a type variable to show that the return type # will always be an instance of whatever ``cls`` is @classmethod def with_circumference(cls: type[C], circumference: float) -> C: """Create a circle with the specified circumference""" radius = circumference / (math.pi * 2) return cls(radius) class Tire(Circle): """A specialised circle (made out of rubber)""" MATERIAL = 'rubber' c = Circle.with_circumference(3) # Ok, variable 'c' has type 'Circle' t = Tire.with_circumference(4) # Ok, variable 't' has type 'Tire' (not 'Circle')
Во время выполнения
isinstance(x, T)
вызоветTypeError
. В общем случаеisinstance()
иissubclass()
не следует использовать с типами.Переменные типа могут быть помечены как ковариантные или контравариантные, передавая
covariant=True
илиcontravariant=True
. Более подробную информацию смотрите в PEP 484. По умолчанию переменные типа инвариантны.
-
class
typing.
ParamSpec
(name, *, bound=None, covariant=False, contravariant=False)¶ Переменная спецификации параметра. Специализированная версия
type variables
.Использование:
P = ParamSpec('P')
Переменные спецификации параметров существуют в основном для пользы статических средств проверки типов. Они используются для передачи типов параметров одного вызываемого объекта другому вызываемому объекту - шаблон, часто встречающийся в функциях высшего порядка и декораторах. Они действительны только при использовании в
Concatenate
, или как первый аргументCallable
, или как параметры для определяемых пользователем Generics. Дополнительную информацию о родовых типах смотрите вGeneric
.Например, чтобы добавить базовое протоколирование в функцию, можно создать декоратор
add_logging
для протоколирования вызовов функции. Переменная спецификации параметров сообщает программе проверки типов, что вызываемая переменная, переданная в декоратор, и возвращаемая им новая вызываемая переменная имеют взаимозависимые параметры типа:from collections.abc import Callable from typing import TypeVar, ParamSpec import logging T = TypeVar('T') P = ParamSpec('P') def add_logging(f: Callable[P, T]) -> Callable[P, T]: '''A type-safe decorator to add logging to a function.''' def inner(*args: P.args, **kwargs: P.kwargs) -> T: logging.info(f'{f.__name__} was called') return f(*args, **kwargs) return inner @add_logging def add_two(x: float, y: float) -> float: '''Add two numbers together.''' return x + y
При отсутствии
ParamSpec
самым простым способом аннотации ранее было использованиеTypeVar
с привязкойCallable[..., Any]
. Однако это вызывает две проблемы:Программа проверки типов не может проверить функцию
inner
, потому что*args
и**kwargs
должны быть набраныAny
.cast()
может потребоваться в теле декоратораadd_logging
при возврате функцииinner
, или статической проверке типов должно быть сказано игнорироватьreturn inner
.
-
args
¶
-
kwargs
¶ Поскольку
ParamSpec
захватывает как позиционные, так и ключевые параметры,P.args
иP.kwargs
можно использовать для разделенияParamSpec
на компоненты.P.args
представляет кортеж позиционных параметров в данном вызове и должен использоваться только для аннотирования*args
.P.kwargs
представляет отображение параметров ключевых слов на их значения в данном вызове и должен использоваться только для аннотирования**kwargs
. Оба атрибута требуют, чтобы аннотируемый параметр находился в области видимости. Во время выполненияP.args
иP.kwargs
являются экземплярамиParamSpecArgs
иParamSpecKwargs
соответственно.
Переменные спецификации параметров, созданные с помощью
covariant=True
илиcontravariant=True
, можно использовать для объявления ковариантных или контравариантных общих типов. Аргументbound
также принимается, аналогичноTypeVar
. Однако фактическая семантика этих ключевых слов еще не определена.Добавлено в версии 3.10.
Примечание
Мариновать можно только переменные спецификации параметров, определенные в глобальной области видимости.
См.также
PEP 612 – Переменные спецификации параметров (PEP, который ввел
ParamSpec
иConcatenate
).
-
typing.
ParamSpecArgs
¶
-
typing.
ParamSpecKwargs
¶ Атрибуты аргументов и ключевых слов аргументов
ParamSpec
. АтрибутP.args
атрибутаParamSpec
является экземпляромParamSpecArgs
, аP.kwargs
является экземпляромParamSpecKwargs
. Они предназначены для интроспекции во время выполнения и не имеют особого значения для статических средств проверки типов.Вызов
get_origin()
на любом из этих объектов вернет исходныйParamSpec
:P = ParamSpec("P") get_origin(P.args) # returns P get_origin(P.kwargs) # returns P
Добавлено в версии 3.10.
-
typing.
AnyStr
¶ AnyStr
- этоconstrained type variable
, определенный какAnyStr = TypeVar('AnyStr', str, bytes)
.Он предназначен для функций, которые могут принимать любые строки, не позволяя смешивать разные типы строк. Например:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat(u"foo", u"bar") # Ok, output has type 'unicode' concat(b"foo", b"bar") # Ok, output has type 'bytes' concat(u"foo", b"bar") # Error, cannot mix unicode and bytes
-
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()) # Passes static type check
Подробности см. в PEP 544. Классы протоколов, украшенные
runtime_checkable()
(описанные позже), действуют как простые протоколы времени выполнения, которые проверяют только наличие заданных атрибутов, игнорируя их сигнатуры типов.Классы протоколов могут быть общими, например:
class GenProto(Protocol[T]): def meth(self) -> T: ...
Добавлено в версии 3.8.
-
@
typing.
runtime_checkable
¶ Пометить класс протокола как протокол времени выполнения.
Такой протокол можно использовать с
isinstance()
иissubclass()
. Это поднимаетTypeError
при применении к классу без протокола. Это позволяет провести простую структурную проверку, очень похожую на «одноруких пони» вcollections.abc
, таких какIterable
. Например:@runtime_checkable class Closable(Protocol): def close(self): ... assert isinstance(open('/some/file'), Closable)
Примечание
runtime_checkable()
будет проверять только наличие необходимых методов, а не их сигнатуры типов. Например,ssl.SSLObject
является классом, поэтому он проходит проверкуissubclass()
на наличиеCallable
. Однако методssl.SSLObject.__init__()
существует только для того, чтобы вызватьTypeError
с более информативным сообщением, что делает невозможным вызов (инстанцирование)ssl.SSLObject
.Добавлено в версии 3.8.
Другие специальные директивы¶
Они не используются в аннотациях. Они являются строительными блоками для объявления типов.
-
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
, оба атрибута являются частью APInamedtuple()
).NamedTuple
подклассы также могут иметь документацию и методы:class Employee(NamedTuple): """Represents an employee.""" 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: Добавлена поддержка значений по умолчанию, методов и docstrings.
Изменено в версии 3.8: Атрибуты
_field_types
и__annotations__
теперь являются обычными словарями, а не экземплярамиOrderedDict
.Изменено в версии 3.9: Удален атрибут
_field_types
в пользу более стандартного атрибута__annotations__
, который содержит ту же информацию.
-
class
typing.
NewType
(name, tp)¶ Вспомогательный класс для указания отдельного типа программе проверки типов, см. NewType. Во время выполнения он возвращает объект, который при вызове возвращает свой аргумент. Использование:
UserId = NewType('UserId', int) first_user = UserId(1)
Добавлено в версии 3.5.2.
Изменено в версии 3.10:
NewType
теперь является классом, а не функцией.
-
class
typing.
TypedDict
(dict)¶ Специальная конструкция для добавления подсказок типа в словарь. Во время выполнения это обычное
dict
.TypedDict
объявляет тип словаря, который ожидает, что все его экземпляры будут иметь определенный набор ключей, где каждый ключ связан со значением согласованного типа. Это ожидание не проверяется во время выполнения, а выполняется только программами проверки типов. Использование:class Point2D(TypedDict): x: int y: int label: str a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
Чтобы позволить использовать эту возможность в старых версиях Python, которые не поддерживают PEP 526,
TypedDict
поддерживает две дополнительные эквивалентные синтаксические формы:Point2D = TypedDict('Point2D', x=int, y=int, label=str) Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
Функциональный синтаксис также следует использовать, если какой-либо из ключей не является допустимым identifiers, например, потому что он является ключевым словом или содержит дефис. Пример:
# raises SyntaxError class Point2D(TypedDict): in: int # 'in' is a keyword x-y: int # name with hyphens # OK, functional syntax Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
По умолчанию все ключи должны присутствовать в
TypedDict
. Это можно отменить, указав значение total. Использование:class Point2D(TypedDict, total=False): x: int y: int
Это означает, что в аргументе
Point2D
TypedDict
может быть опущен любой из ключей. Ожидается, что средство проверки типов будет поддерживать только литералFalse
илиTrue
в качестве значения аргументаtotal
.True
используется по умолчанию и делает обязательными все элементы, определенные в теле класса.Тип
TypedDict
может наследоваться от одного или нескольких других типовTypedDict
, используя синтаксис, основанный на классах. Использование:class Point3D(Point2D): z: int
Point3D
имеет три элемента:x
,y
иz
. Это эквивалентно такому определению:class Point3D(TypedDict): x: int y: int z: int
Класс
TypedDict
не может наследоваться от неклассаTypedDict
, в том числеGeneric
. Например:class X(TypedDict): x: int class Y(TypedDict): y: int class Z(object): pass # A non-TypedDict class class XY(X, Y): pass # OK class XZ(X, Z): pass # raises TypeError T = TypeVar('T') class XT(X, Generic[T]): pass # raises TypeError
Аннотация
TypedDict
может быть проанализирована с помощью аннотаций dicts (см. Лучшие методы работы с аннотациями для получения дополнительной информации о лучших практиках аннотаций),__total__
,__required_keys__
и__optional_keys__
.-
__total__
¶ Point2D.__total__
дает значение аргументаtotal
. Пример:>>> from typing import TypedDict >>> class Point2D(TypedDict): pass >>> Point2D.__total__ True >>> class Point2D(TypedDict, total=False): pass >>> Point2D.__total__ False >>> class Point3D(Point2D): pass >>> Point3D.__total__ True
-
__required_keys__
¶ Добавлено в версии 3.9.
-
__optional_keys__
¶ Point2D.__required_keys__
иPoint2D.__optional_keys__
возвращаютfrozenset
объекты, содержащие требуемые и не требуемые ключи соответственно. В настоящее время единственным способом объявления требуемых и не требуемых ключей в одном и том жеTypedDict
является смешанное наследование, при котором объявляетсяTypedDict
с одним значением для аргументаtotal
и затем наследуется от другогоTypedDict
с другим значением дляtotal
. Использование:>>> class Point2D(TypedDict, total=False): ... x: int ... y: int ... >>> class Point3D(Point2D): ... z: int ... >>> Point3D.__required_keys__ == frozenset({'z'}) True >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) True
Добавлено в версии 3.9.
Дополнительные примеры и подробные правила использования PEP 589 смотрите в
TypedDict
.Добавлено в версии 3.8.
-
Общие конкретные коллекции¶
Соответствие встроенным типам¶
-
class
typing.
Dict
(dict, MutableMapping[KT, VT])¶ Обобщенная версия
dict
. Полезен для аннотирования типов возврата. Для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, такой какMapping
.Этот тип может быть использован следующим образом:
def count_words(text: str) -> Dict[str, int]: ...
Не рекомендуется, начиная с версии 3.9:
builtins.dict
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
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]
Не рекомендуется, начиная с версии 3.9:
builtins.list
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Set
(set, MutableSet[T])¶ Обобщенная версия
builtins.set
. Полезен для аннотирования типов возврата. Для аннотирования аргументов предпочтительнее использовать абстрактный тип коллекции, такой какAbstractSet
.Не рекомендуется, начиная с версии 3.9:
builtins.set
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
FrozenSet
(frozenset, AbstractSet[T_co])¶ Обобщенная версия
builtins.frozenset
.Не рекомендуется, начиная с версии 3.9:
builtins.frozenset
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
Примечание
Tuple
является специальной формой.
Соответствие типам в collections
¶
-
class
typing.
DefaultDict
(collections.defaultdict, MutableMapping[KT, VT])¶ Обобщенная версия
collections.defaultdict
.Добавлено в версии 3.5.2.
Не рекомендуется, начиная с версии 3.9:
collections.defaultdict
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
OrderedDict
(collections.OrderedDict, MutableMapping[KT, VT])¶ Обобщенная версия
collections.OrderedDict
.Добавлено в версии 3.7.2.
Не рекомендуется, начиная с версии 3.9:
collections.OrderedDict
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
ChainMap
(collections.ChainMap, MutableMapping[KT, VT])¶ Обобщенная версия
collections.ChainMap
.Добавлено в версии 3.5.4.
Добавлено в версии 3.6.1.
Не рекомендуется, начиная с версии 3.9:
collections.ChainMap
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Counter
(collections.Counter, Dict[T, int])¶ Обобщенная версия
collections.Counter
.Добавлено в версии 3.5.4.
Добавлено в версии 3.6.1.
Не рекомендуется, начиная с версии 3.9:
collections.Counter
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Deque
(deque, MutableSequence[T])¶ Обобщенная версия
collections.deque
.Добавлено в версии 3.5.4.
Добавлено в версии 3.6.1.
Не рекомендуется, начиная с версии 3.9:
collections.deque
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
Другие виды бетона¶
-
class
typing.
IO
¶ -
class
typing.
TextIO
¶ -
class
typing.
BinaryIO
¶ Общий тип
IO[AnyStr]
и его подклассыTextIO(IO[str])
иBinaryIO(IO[bytes])
представляют типы потоков ввода-вывода, такие как возвращаемыеopen()
.Deprecated since version 3.8, will be removed in version 3.12: Пространство имен
typing.io
устарело и будет удалено. Вместо этого эти типы следует напрямую импортировать изtyping
.
-
class
typing.
Pattern
¶ -
class
typing.
Match
¶ Эти псевдонимы типов соответствуют возвращаемым типам из
re.compile()
иre.match()
. Эти типы (и соответствующие функции) являются общими вAnyStr
и могут быть конкретизированы путем написанияPattern[str]
,Pattern[bytes]
,Match[str]
илиMatch[bytes]
.Deprecated since version 3.8, will be removed in version 3.12: Пространство имен
typing.re
устарело и будет удалено. Вместо этого эти типы следует напрямую импортировать изtyping
.Не рекомендуется, начиная с версии 3.9: Классы
Pattern
иMatch
изre
теперь поддерживают[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Text
¶ Text
является псевдонимом дляstr
. Он предусмотрен для обеспечения совместимости с прямым путем для кода Python 2: в Python 2Text
является псевдонимом дляunicode
.Используйте
Text
, чтобы указать, что значение должно содержать строку юникода способом, совместимым как с Python 2, так и с Python 3:def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
Добавлено в версии 3.5.2.
Абстрактные базовые классы¶
Соответствие коллекциям в collections.abc
.¶
-
class
typing.
AbstractSet
(Sized, Collection[T_co])¶ Обобщенная версия
collections.abc.Set
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Set
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
ByteString
(Sequence[int])¶ Обобщенная версия
collections.abc.ByteString
.Этот тип представляет типы
bytes
,bytearray
иmemoryview
последовательностей байтов.Как сокращение для этого типа,
bytes
может быть использовано для аннотации аргументов любого из типов, упомянутых выше.Не рекомендуется, начиная с версии 3.9:
collections.abc.ByteString
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Collection
(Sized, Iterable[T_co], Container[T_co])¶ Обобщенная версия
collections.abc.Collection
.Добавлено в версии 3.6.0.
Не рекомендуется, начиная с версии 3.9:
collections.abc.Collection
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Container
(Generic[T_co])¶ Обобщенная версия
collections.abc.Container
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Container
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
ItemsView
(MappingView, Generic[KT_co, VT_co])¶ Обобщенная версия
collections.abc.ItemsView
.Не рекомендуется, начиная с версии 3.9:
collections.abc.ItemsView
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
KeysView
(MappingView[KT_co], AbstractSet[KT_co])¶ Обобщенная версия
collections.abc.KeysView
.Не рекомендуется, начиная с версии 3.9:
collections.abc.KeysView
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
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]
Не рекомендуется, начиная с версии 3.9:
collections.abc.Mapping
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
MappingView
(Sized, Iterable[T_co])¶ Обобщенная версия
collections.abc.MappingView
.Не рекомендуется, начиная с версии 3.9:
collections.abc.MappingView
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
MutableMapping
(Mapping[KT, VT])¶ Обобщенная версия
collections.abc.MutableMapping
.Не рекомендуется, начиная с версии 3.9:
collections.abc.MutableMapping
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
MutableSequence
(Sequence[T])¶ Обобщенная версия
collections.abc.MutableSequence
.Не рекомендуется, начиная с версии 3.9:
collections.abc.MutableSequence
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
MutableSet
(AbstractSet[T])¶ Обобщенная версия
collections.abc.MutableSet
.Не рекомендуется, начиная с версии 3.9:
collections.abc.MutableSet
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Sequence
(Reversible[T_co], Collection[T_co])¶ Обобщенная версия
collections.abc.Sequence
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Sequence
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
ValuesView
(MappingView[VT_co])¶ Обобщенная версия
collections.abc.ValuesView
.Не рекомендуется, начиная с версии 3.9:
collections.abc.ValuesView
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
Соответствие другим типам в collections.abc
.¶
-
class
typing.
Iterable
(Generic[T_co])¶ Обобщенная версия
collections.abc.Iterable
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Iterable
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Iterator
(Iterable[T_co])¶ Обобщенная версия
collections.abc.Iterator
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Iterator
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
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'
Обратите внимание, что в отличие от многих других дженериков в модуле типизации,
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
Не рекомендуется, начиная с версии 3.9:
collections.abc.Generator
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Hashable
¶ Псевдоним для
collections.abc.Hashable
.
-
class
typing.
Reversible
(Iterable[T_co])¶ Обобщенная версия
collections.abc.Reversible
.Не рекомендуется, начиная с версии 3.9:
collections.abc.Reversible
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Sized
¶ Псевдоним для
collections.abc.Sized
.
Асинхронное программирование¶
-
class
typing.
Coroutine
(Awaitable[V_co], Generic[T_co, T_contra, V_co])¶ Обобщенная версия
collections.abc.Coroutine
. Дисперсия и порядок переменных типа соответствуют таковым вGenerator
, например:from collections.abc import Coroutine c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere x = c.send('hi') # Inferred type of 'x' is list[str] async def bar() -> None: y = await c # Inferred type of 'y' is int
Добавлено в версии 3.5.3.
Не рекомендуется, начиная с версии 3.9:
collections.abc.Coroutine
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
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.
Не рекомендуется, начиная с версии 3.9:
collections.abc.AsyncGenerator
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
AsyncIterable
(Generic[T_co])¶ Обобщенная версия
collections.abc.AsyncIterable
.Добавлено в версии 3.5.2.
Не рекомендуется, начиная с версии 3.9:
collections.abc.AsyncIterable
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
AsyncIterator
(AsyncIterable[T_co])¶ Обобщенная версия
collections.abc.AsyncIterator
.Добавлено в версии 3.5.2.
Не рекомендуется, начиная с версии 3.9:
collections.abc.AsyncIterator
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
Awaitable
(Generic[T_co])¶ Обобщенная версия
collections.abc.Awaitable
.Добавлено в версии 3.5.2.
Не рекомендуется, начиная с версии 3.9:
collections.abc.Awaitable
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
Типы контекстных менеджеров¶
-
class
typing.
ContextManager
(Generic[T_co])¶ Обобщенная версия
contextlib.AbstractContextManager
.Добавлено в версии 3.5.4.
Добавлено в версии 3.6.0.
Не рекомендуется, начиная с версии 3.9:
contextlib.AbstractContextManager
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
-
class
typing.
AsyncContextManager
(Generic[T_co])¶ Обобщенная версия
contextlib.AbstractAsyncContextManager
.Добавлено в версии 3.5.4.
Добавлено в версии 3.6.2.
Не рекомендуется, начиная с версии 3.9:
contextlib.AbstractAsyncContextManager
теперь поддерживает[]
. См. PEP 585 и Общий тип псевдонима.
Протоколы¶
Эти протоколы украшаются символом runtime_checkable()
.
-
class
typing.
SupportsAbs
¶ ABC с одним абстрактным методом
__abs__
, который является ковариантным в своем возвращаемом типе.
-
class
typing.
SupportsBytes
¶ ABC с одним абстрактным методом
__bytes__
.
-
class
typing.
SupportsComplex
¶ ABC с одним абстрактным методом
__complex__
.
-
class
typing.
SupportsFloat
¶ ABC с одним абстрактным методом
__float__
.
-
class
typing.
SupportsIndex
¶ ABC с одним абстрактным методом
__index__
.Добавлено в версии 3.8.
-
class
typing.
SupportsInt
¶ ABC с одним абстрактным методом
__int__
.
-
class
typing.
SupportsRound
¶ ABC с одним абстрактным методом
__round__
, который является ковариантным в своем возвращаемом типе.
Функции и декораторы¶
-
typing.
cast
(typ, val)¶ Приведение значения к типу.
Это возвращает значение без изменений. Для программы проверки типов это сигнал, что возвращаемое значение имеет заданный тип, но во время выполнения мы намеренно ничего не проверяем (мы хотим, чтобы это было как можно быстрее).
-
@
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: # Error reported by type checker ... @final class Leaf: ... class Other(Leaf): # Error reported by type checker ...
Проверка этих свойств во время выполнения не предусмотрена. Более подробную информацию см. в разделе PEP 591.
Добавлено в версии 3.8.
-
@
typing.
no_type_check
¶ Декоратор, указывающий, что аннотации не являются подсказками типов.
Это работает как класс или функция decorator. В случае класса он применяется рекурсивно ко всем методам, определенным в этом классе (но не к методам, определенным в его суперклассах или подклассах).
Это мутирует функцию(и) на месте.
-
@
typing.
no_type_check_decorator
¶ Декоратор для придания другому декоратору эффекта
no_type_check()
.Это оборачивает декоратор чем-то, что оборачивает декорируемую функцию в
no_type_check()
.
-
@
typing.
type_check_only
¶ Декоратор для пометки класса или функции как недоступной во время выполнения.
Этот декоратор сам по себе недоступен во время выполнения. В основном он предназначен для маркировки классов, определенных в файлах-заглушках типов, если реализация возвращает экземпляр частного класса:
@type_check_only class Response: # private or not available at runtime code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
Обратите внимание, что возвращать экземпляры частных классов не рекомендуется. Обычно предпочтительнее сделать такие классы общедоступными.
Помощники интроспекции¶
-
typing.
get_type_hints
(obj, globalns=None, localns=None, include_extras=False)¶ Возвращает словарь, содержащий подсказки типов для функции, метода, модуля или объекта класса.
Часто это то же самое, что и
obj.__annotations__
. Кроме того, прямые ссылки, закодированные как строковые литералы, обрабатываются путем их оценки в пространствах именglobals
иlocals
. Если необходимо,Optional[t]
добавляется для аннотаций функций и методов, если установлено значение по умолчанию, равноеNone
. Для классаC
возвращается словарь, построенный путем объединения всех__annotations__
вдольC.__mro__
в обратном порядке.Функция рекурсивно заменяет все
Annotated[T, ...]
наT
, если толькоinclude_extras
не установлено наTrue
(см.Annotated
для получения дополнительной информации). Например:class Student(NamedTuple): name: Annotated[str, 'some marker'] get_type_hints(Student) == {'name': str} get_type_hints(Student, include_extras=False) == {'name': str} get_type_hints(Student, include_extras=True) == { 'name': Annotated[str, 'some marker'] }
Примечание
get_type_hints()
не работает с импортированными type aliases, которые включают прямые ссылки. Включение отложенной оценки аннотаций (PEP 563) может устранить необходимость в большинстве прямых ссылок.Изменено в версии 3.9: Добавлен параметр
include_extras
как часть параметра PEP 593.
-
typing.
get_args
(tp)¶
-
typing.
get_origin
(tp)¶ Обеспечить базовую интроспекцию для общих типов и специальных форм типизации.
Для типизированного объекта вида
X[Y, Z, ...]
эти функции возвращаютX
и(Y, Z, ...)
. ЕслиX
является общим псевдонимом для встроенного илиcollections
класса, он нормализуется до исходного класса. ЕслиX
является объединением илиLiteral
содержится в другом родовом типе, порядок(Y, Z, ...)
может отличаться от порядка исходных аргументов[Y, Z, ...]
из-за кэширования типов. Для неподдерживаемых объектов возвращаются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.
is_typeddict
(tp)¶ Проверьте, является ли тип
TypedDict
.Например:
class Film(TypedDict): title: str year: int is_typeddict(Film) # => True is_typeddict(list | str) # => False
Добавлено в версии 3.10.
-
class
typing.
ForwardRef
¶ Класс, используемый для внутреннего типового представления строковых прямых ссылок. Например,
List["SomeClass"]
неявно преобразуется вList[ForwardRef("SomeClass")]
. Этот класс не должен инстанцироваться пользователем, но может использоваться инструментами интроспекции.Примечание
Общие типы PEP 585, такие как
list["SomeClass"]
, не будут неявно преобразованы вlist[ForwardRef("SomeClass")]
и, следовательно, не будут автоматически разрешаться вlist[SomeClass]
.Добавлено в версии 3.7.4.
Постоянная¶
-
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()
Первая аннотация типа должна быть заключена в кавычки, что делает ее «прямой ссылкой», чтобы скрыть ссылку
expensive_mod
от времени выполнения интерпретатора. Аннотации типов для локальных переменных не оцениваются, поэтому вторую аннотацию не нужно заключать в кавычки.Примечание
Если используется
from __future__ import annotations
, аннотации не оцениваются во время определения функции. Вместо этого они хранятся в виде строк в__annotations__
. Это делает ненужным использование кавычек вокруг аннотации (см. PEP 563).Добавлено в версии 3.5.2.