Содержание страницы
typing – Поддержка аннотаций типов¶typing – Support for type hints
Добавлено в версии 3.5.
Исходный код: Lib/typing.py
Примечание
Среда выполнения Python не проверяет аннотации типов функций и переменных. Они могут использоваться сторонними инструментами, такими как проверщики типов, IDE, линтеры и т. д.
Этот модуль обеспечивает поддержку аннотаций типов во время выполнения.
Рассмотрим следующую функцию:
def surface_area_of_cube(edge_length: float) -> str:
return f"The surface area of the cube is {6 * edge_length ** 2}."
Функция surface_area_of_cube принимает аргумент, который должен
быть экземпляром float, на что указывает аннотация типа
edge_length: float. Функция должна возвращать экземпляр
str, на что указывает аннотация -> str.
Хотя аннотации типов могут быть простыми классами, такими как float или str,
они также могут быть более сложными. Модуль typing предоставляет набор
более продвинутых аннотаций типов.
Новые функции часто добавляются в модуль typing.
Пакет typing_extensions
предоставляет бэкпорты этих новых функций для старых версий Python.
См. также
- «Шпаргалка по аннотациям типов»
Краткий обзор аннотаций типов (размещён в документации mypy)
- Раздел «Type System Reference» документации mypy
Система типов Python стандартизирована через PEP, поэтому данное руководство должно в целом подходить для большинства проверщиков типов Python. (Некоторые части могут по-прежнему относиться только к mypy.)
- «Статическая типизация в Python»
Независимая от проверщика типов документация, написанная сообществом, с подробным описанием возможностей системы типов, полезных инструментов, связанных с типизацией, и лучших практик типизации.
Спецификация системы типов Python¶Specification for the Python Type System
Каноническая, актуальная спецификация системы типов Python находится в «Specification for the Python type system».
Псевдонимы типов¶Type aliases
Псевдоним типа определяется с помощью оператора type, который создаёт
экземпляр TypeAliasType. В этом примере
Vector и list[float] будут рассматриваться статическими проверщиками типов как эквивалентные:
type 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 collections.abc import Sequence
type ConnectionOptions = dict[str, str]
type Address = tuple[str, int]
type 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:
...
Оператор type появился в Python 3.12. Для обратной
совместимости псевдонимы типов также можно создавать с помощью простого присваивания:
Vector = list[float]
Или помечены TypeAlias, чтобы было явно указано, что это псевдоним типа,
а не обычное присваивание переменной:
from typing import TypeAlias
Vector: TypeAlias = list[float]
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.
Примечание
Напомним, что использование псевдонима типа объявляет два типа эквивалентными друг другу. Использование type Alias = Original заставит статический анализатор типов считать Alias точно эквивалентным Original во всех случаях. Это полезно, когда требуется упростить сложные сигнатуры типов.
В отличие от этого, NewType объявляет один тип подтипом другого. Использование Derived = NewType('Derived', Original) заставит статический анализатор типов считать Derived подклассом Original, что означает, что значение типа Original не может использоваться там, где ожидается значение типа Derived. Это полезно для предотвращения логических ошибок с минимальными затратами времени выполнения.
Добавлено в версии 3.5.2.
Изменено в версии 3.10: NewType теперь является классом, а не функцией. В результате имеются некоторые дополнительные расходы во время выполнения при вызове NewType по сравнению с обычной функцией.
Изменено в версии 3.11: Производительность вызова NewType восстановлена до уровня Python 3.9.
Аннотация вызываемых объектов¶Annotating callable objects
Функции – или другие вызываемые объекты – могут быть аннотированы с помощью
collections.abc.Callable или устаревшего typing.Callable.
Callable[[int], str] обозначает функцию, которая принимает один параметр
типа int и возвращает str.
Например:
from collections.abc import Callable, Awaitable
def feeder(get_next_item: Callable[[], str]) -> None:
... # Тело
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
... # Тело
async def on_update(value: str) -> None:
... # Тело
callback: Callable[[str], Awaitable[None]] = on_update
Синтаксис индексации всегда должен использоваться ровно с двумя значениями: списком аргументов и типом возвращаемого значения. Список аргументов должен быть списком типов, ParamSpec, Concatenate или многоточием. Тип возвращаемого значения должен быть единственным типом.
Если в качестве списка аргументов указано литеральное многоточие ..., это означает, что принимается вызываемый объект с произвольным списком параметров:
def concat(x: str, y: str) -> str:
return x + y
x: Callable[..., str]
x = str # ОК
x = concat # Тоже ОК
Callable не может выражать сложные сигнатуры, такие как функции, принимающие переменное количество аргументов, перегруженные функции или функции, имеющие только ключевые параметры. Однако эти сигнатуры можно выразить, определив класс Protocol с методом __call__():
from collections.abc import Iterable
from typing import Protocol
class Combiner(Protocol):
def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...
def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes:
for item in data:
...
def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]:
...
def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]:
...
batch_proc([], good_cb) # ОК
batch_proc([], bad_cb) # Ошибка! Аргумент 2 имеет несовместимый тип из-за
# другого имени и вида в колбэке
Объекты, принимающие другие вызываемые объекты в качестве аргументов, могут указать, что их типы параметров зависят друг от друга, с помощью ParamSpec. Кроме того, если такой вызываемый объект добавляет или удаляет аргументы из других вызываемых объектов, может использоваться оператор Concatenate. Они имеют соответственно форму Callable[ParamSpecVariable, ReturnType] и Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType].
Changed in version 3.10: Callable now supports ParamSpec and Concatenate.
See PEP 612 for more details.
См. также
В документации к ParamSpec и Concatenate приведены примеры использования в Callable.
Обобщённые типы¶Generics
Поскольку информацию о типах объектов, хранящихся в контейнерах, невозможно статически вывести обобщённым способом, многие классы контейнеров в стандартной библиотеке поддерживают индексацию для указания ожидаемых типов элементов контейнера.
from collections.abc import Mapping, Sequence
class Employee: ...
# Sequence[Employee] означает, что все элементы последовательности
# должны быть экземплярами "Employee".
# Mapping[str, str] означает, что все ключи и все значения в отображении
# должны быть строками.
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
Обобщённые функции и классы могут быть параметризованы с помощью синтаксиса параметров типа:
from collections.abc import Sequence
def first[T](l: Sequence[T]) -> T: # Функция универсальна (обобщена) по TypeVar "T"
return l[0]
Или с помощью непосредственного использования фабрики TypeVar:
from collections.abc import Sequence
from typing import TypeVar
U = TypeVar('U') # Объявить переменную типа "U"
def second(l: Sequence[U]) -> U: # Функция универсальна (обобщена) по TypeVar "U"
return l[1]
Изменено в версии 3.12: Синтаксическая поддержка обобщённых типов новая в Python 3.12.
Аннотация кортежей¶Annotating tuples
Для большинства контейнеров в Python система типов предполагает, что все элементы в контейнере будут одного типа. Например:
from collections.abc import Mapping
# Проверка типов выведет, что все элементы в ``x`` должны иметь тип int.
x: list[int] = []
# Ошибка проверки типов: ``list`` принимает только один аргумент типа:
y: list[int, str] = [1, 'foo']
# Проверка типов выведет, что все ключи в ``z`` должны быть строками,
# а все значения в ``z`` должны быть строками или int.
z: Mapping[str, str | int] = {}
list принимает только один аргумент типа, поэтому анализатор типов выдал бы ошибку на присваивании y выше. Аналогично,
Mapping принимает только два аргумента типа: первый указывает тип ключей, а второй – тип значений.
Однако, в отличие от большинства других контейнеров Python, в идиоматическом коде Python часто встречаются кортежи, элементы которых не все одного типа. По этой причине кортежи обрабатываются особым образом в системе типов Python. tuple
принимает любое количество аргументов типа:
# OK: ``x`` присваивается кортежу длины 1, единственный элемент которого – int.
x: tuple[int] = (5,)
# OK: ``y`` присваивается кортежу длины 2;
# элемент 1 – int, элемент 2 – str.
y: tuple[int, str] = (5, "foo")
# Ошибка: аннотация типа указывает на кортеж длины 1,
# но ``z`` был присвоен кортеж длины 3.
z: tuple[int] = (1, 2, 3)
Для обозначения кортежа, который может быть любой длины, и в котором все элементы одного типа T, используйте tuple[T, ...]. Для обозначения пустого кортежа используйте tuple[()]. Использование простого tuple в качестве аннотации эквивалентно использованию tuple[Any, ...]:
x: tuple[int, ...] = (1, 2)
# Эти переприсваивания OK: ``tuple[int, ...]`` указывает, что x может быть любой длины.
x = (1, 2, 3)
x = ()
# Это переприсваивание – ошибка: все элементы в ``x`` должны быть int.
x = ("foo", "bar")
# ``y`` может быть присвоен только пустому кортежу.
y: tuple[()] = ()
z: tuple = ("foo", "bar")
# Эти переприсваивания OK: простой ``tuple`` эквивалентен ``tuple[Any, ...]``.
z = (1, 2, 3)
z = ()
Тип объектов классов¶The type of class objects
Переменная, аннотированная C, может принимать значение типа C. В отличие от этого, переменная, аннотированная type[C] (или устаревшим typing.Type[C]), может принимать значения, которые сами являются классами – точнее, она будет принимать объект класса C. Например:
a = 3 # Имеет тип ``int``.
b = int # Имеет тип ``type[int]``.
c = type(a) # Также имеет тип ``type[int]``.
Обратите внимание, что type[C] ковариантен:
class User: ...
class ProUser(User): ...
class TeamUser(User): ...
def make_new_user(user_class: type[User]) -> User:
# ...
return user_class()
make_new_user(User) # ОК
make_new_user(ProUser) # Также OK: ``type[ProUser]`` – подтип ``type[User]``.
make_new_user(TeamUser) # По-прежнему допустимо.
make_new_user(User()) # Ошибка: ожидался ``type[User]``, но получен ``User``.
make_new_user(int) # Ошибка: ``type[int]`` не является подтипом ``type[User]``.
Единственными допустимыми параметрами для type являются классы, Any,
переменные типа и объединения любых из этих типов.
Например:
def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
new_non_team_user(BasicUser) # ОК
new_non_team_user(ProUser) # ОК
new_non_team_user(TeamUser) # Ошибка: ``type[TeamUser]`` не является подтипом
# ``type[BasicUser | ProUser]``.
new_non_team_user(User) # Тоже ошибка.
type[Any] эквивалентно type, который является корнем иерархии метаклассов Python.
Аннотация генераторов и корутин¶Annotating generators and coroutines
Генератор можно аннотировать с помощью обобщённого типа
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
Асинхронные генераторы обрабатываются аналогичным образом, но не ожидают аргумента типа ReturnType (AsyncGenerator[YieldType, SendType]):
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)
Корутины можно аннотировать с помощью Coroutine[YieldType, SendType, ReturnType]. Обобщённые аргументы соответствуют аргументам Generator, например:
from collections.abc import Coroutine
c: Coroutine[list[str], str, int] # Некоторая корутина, определённая в другом месте.
x = c.send('hi') # Выведенный тип 'x' – list[str].
async def bar() -> None:
y = await c # Выведенный тип 'y' – int.
Пользовательские обобщённые типы¶User-defined generic types
Пользовательский класс можно определить как обобщённый класс.
from logging import Logger
class LoggedVar[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)
Этот синтаксис означает, что класс LoggedVar параметризован одной переменной типа T. Это также делает T допустимым типом в теле класса.
Обобщённые классы неявно наследуются от Generic. Для совместимости с Python 3.11 и ниже можно также явно наследоваться от Generic, чтобы указать обобщённый класс:
from typing import TypeVar, Generic
T = TypeVar('T')
class LoggedVar(Generic[T]):
...
Обобщённые классы имеют методы __class_getitem__(), что означает возможность параметризации во время выполнения (например, LoggedVar[int] ниже):
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
class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]:
...
OldT = TypeVar('OldT', contravariant=True)
OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True)
OldS = TypeVar('OldS', int, str)
class OldWeirdTrio(Generic[OldT, OldB, OldS]):
...
Каждый аргумент-переменная типа для Generic должен быть уникальным. Поэтому такой код некорректен:
from typing import TypeVar, Generic
...
class Pair[M, M]: # SyntaxError
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
Обобщённые классы также могут наследоваться от других классов:
from collections.abc import Sized
class LinkedList[T](Sized):
...
При наследовании от обобщённых классов некоторые параметры типа могут быть фиксированными:
from collections.abc import Mapping
class MyDict[T](Mapping[str, T]):
...
В этом случае MyDict имеет один параметр – T.
Использование обобщённого класса без указания параметров типа подразумевает Any для каждой позиции. В следующем примере MyIterable не является обобщённым, но неявно наследуется от Iterable[Any]:
from collections.abc import Iterable
class MyIterable(Iterable): # То же, что и Iterable[Any].
...
Также поддерживаются пользовательские псевдонимы обобщённых типов. Примеры:
from collections.abc import Iterable
type Response[S] = Iterable[S] | int
# Тип возвращаемого значения здесь такой же, как Iterable[str] | int
def response(query: str) -> Response[str]:
...
type Vec[T] = Iterable[tuple[T, T]]
def inproduct[T: (int, float, complex)](v: Vec[T]) -> T: # То же, что и Iterable[tuple[T, T]]
return sum(x*y for x, y in v)
Для обратной совместимости псевдонимы обобщённых типов можно также создать простым присваиванием:
from collections.abc import Iterable
from typing import TypeVar
S = TypeVar("S")
Response = Iterable[S] | int
Изменено в версии 3.7: Generic больше не имеет собственного метакласса.
Изменено в версии 3.12: Синтаксическая поддержка обобщений и псевдонимов типов появилась в версии 3.12. Ранее обобщённые классы должны были явно наследоваться от Generic или содержать переменную типа в одной из своих баз.
Пользовательские обобщённые типы для выражений параметров также поддерживаются через переменные спецификации параметров в форме [**P]. Поведение согласуется с описанными выше переменными типов, так как переменные спецификации параметров обрабатываются модулем typing как специализированные переменные типов. Единственное исключение состоит в том, что список типов может использоваться для подстановки ParamSpec:
>>> class Z[T, **P]: ... # T – это TypeVar; P – это ParamSpec
...
>>> Z[int, [dict, float]]
__main__.Z[int, [dict, float]]
Классы, обобщённые по ParamSpec, также можно создать с помощью явного наследования от Generic. В этом случае ** не используется:
from typing import ParamSpec, Generic
P = ParamSpec('P')
class Z(Generic[P]):
...
Ещё одно различие между TypeVar и ParamSpec заключается в том, что обобщение только с одной переменной спецификации параметров принимает списки параметров в виде X[[Type1, Type2, ...]], а также X[Type1, Type2, ...] из эстетических соображений. Внутренне последняя форма преобразуется в первую, поэтому следующие варианты эквивалентны:
>>> class X[**P]: ...
...
>>> X[int, str]
__main__.X[[int, str]]
>>> X[[int, str]]
__main__.X[[int, str]]
Обратите внимание: обобщения с ParamSpec могут не иметь корректного __parameters__ после подстановки в некоторых случаях, поскольку они предназначены в первую очередь для статической проверки типов.
Изменено в версии 3.10: Generic теперь можно параметризовать по выражениям параметров. Подробнее см. ParamSpec и PEP 612.
Пользовательский обобщённый класс может иметь ABC в качестве базовых классов без конфликта метаклассов. Обобщённые метаклассы не поддерживаются. Результат параметризации обобщённых типов кэшируется, и большинство типов в модуле typing являются хэшируемыми и сравнимыми на равенство.
Тип Any¶The Any type
Особым видом типа является Any. Статический проверяющий типов будет считать каждый тип совместимым с Any, а Any – совместимым с каждым типом.
Это означает, что над значением типа Any можно выполнять любые операции или вызовы методов и присваивать его любой переменной:
from typing import Any
a: Any = None
a = [] # ОК
a = 2 # ОК
s: 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 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: # Примечание: базовые классы отсутствуют
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Проходит проверку типов
Более того, наследуя специальный класс Protocol, пользователь
может определять новые пользовательские протоколы, чтобы в полной мере использовать структурное подтипирование
(см. примеры ниже).
Содержимое модуля¶Module contents
Модуль typing определяет следующие классы, функции и декораторы.
Специальные примитивы типизации¶Special typing primitives
Специальные типы¶Special types
Их можно использовать в качестве типов в аннотациях. Они не поддерживают подписку
с помощью [].
- typing.Any¶
Специальный тип, указывающий на неограниченный тип.
Изменено в версии 3.11:
Anyтеперь можно использовать в качестве базового класса. Это может быть полезно для предотвращения ошибок проверки типов в классах, которые могут использовать утиную типизацию где угодно или являются сильно динамичными.
- typing.AnyStr¶
-
Определение:
AnyStr = TypeVar('AnyStr', str, bytes)
AnyStrпредназначен для функций, которые могут принимать аргументы типаstrилиbytes, но не допускают их смешивания.Например:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat("foo", "bar") # OK, результат имеет тип 'str' concat(b"foo", b"bar") # OK, результат имеет тип 'bytes' concat("foo", b"bar") # Ошибка, нельзя смешивать str и bytes
Обратите внимание, что, несмотря на название,
AnyStrне имеет никакого отношения к типуAnyи не означает «любая строка». В частности,AnyStrиstr | bytesотличаются друг от друга и имеют разные сценарии использования:# Неверное использование AnyStr: # Переменная типа используется только один раз в сигнатуре функции, # поэтому не может быть «решена» проверщиком типов def greet_bad(cond: bool) -> AnyStr: return "hi there!" if cond else b"greetings!" # Лучший способ аннотировать эту функцию: def greet_proper(cond: bool) -> str | bytes: return "hi there!" if cond else b"greetings!"
- typing.LiteralString¶
Специальный тип, включающий только строковые литералы.
Любой строковый литерал совместим с
LiteralString, как и другойLiteralString. Однако объект, типизированный просто какstr, – нет. Строка, созданная композицией объектов типаLiteralString, также приемлема какLiteralString.Пример:
def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: run_query("SELECT * FROM students") # ОК run_query(literal_string) # ОК run_query("SELECT * FROM " + literal_string) # ОК run_query(arbitrary_string) # ошибка проверки типов run_query( # ошибка проверки типов f"SELECT * FROM students WHERE name = {arbitrary_string}" )
LiteralStringполезен для чувствительных API, где произвольные пользовательские строки могут создавать проблемы. Например, два приведённых выше случая, которые вызывают ошибки проверки типов, могут быть уязвимы для SQL-инъекций.Подробнее см. PEP 675.
Добавлено в версии 3.12.
- typing.Never¶
- typing.NoReturn¶
NeverиNoReturnпредставляют нижний тип, тип, не имеющий элементов.Их можно использовать для обозначения того, что функция никогда не возвращает значение, например
sys.exit():from typing import Never # или NoReturn def stop() -> Never: raise RuntimeError('no way')
Или для определения функции, которая никогда не должна вызываться, поскольку нет допустимых аргументов, например
assert_never():from typing import Never # или NoReturn def never_call_me(arg: Never) -> None: pass def int_or_str(arg: int | str) -> None: never_call_me(arg) # ошибка проверки типов match arg: case int(): print("It's an int") case str(): print("It's a str") case _: never_call_me(arg) # OK, аргумент имеет тип Never (или NoReturn)
NeverиNoReturnимеют одинаковое значение в системе типов, и статические анализаторы типов обрабатывают их одинаково.Добавлено в версии 3.6.2: Добавлен
NoReturn.Добавлено в версии 3.11: Добавлен
Never.
- typing.Self¶
Специальный тип для представления текущего вложенного класса.
Например:
from typing import Self, reveal_type class Foo: def return_self(self) -> Self: ... return self class SubclassOfFoo(Foo): pass reveal_type(Foo().return_self()) # Раскрытый тип – "Foo" reveal_type(SubclassOfFoo().return_self()) # Раскрытый тип – "SubclassOfFoo"
Эта аннотация семантически эквивалентна следующему, хотя и в более краткой форме:
from typing import TypeVar Self = TypeVar("Self", bound="Foo") class Foo: def return_self(self: Self) -> Self: ... return self
В общем случае, если что-то возвращает
self, как в примерах выше, следует использоватьSelfв качестве аннотации возвращаемого типа. ЕслиFoo.return_selfбыл аннотирован как возвращающий"Foo", то анализатор типов выведет, что объект, возвращённый изSubclassOfFoo.return_self, имеет типFoo, а неSubclassOfFoo.Другие распространённые случаи использования включают:
classmethod, которые используются как альтернативные конструкторы и возвращают экземпляры параметраcls.Аннотирование метода
__enter__(), который возвращает self.
Не следует использовать
Selfв качестве аннотации возвращаемого типа, если метод не гарантирует возврат экземпляра подкласса при наследовании класса:class Eggs: # Self здесь была бы некорректной аннотацией возврата, # так как возвращаемый объект всегда является экземпляром Eggs, # даже в подклассах. def returns_eggs(self) -> "Eggs": return Eggs()
См. PEP 673 для получения дополнительных сведений.
Добавлено в версии 3.12.
- typing.TypeAlias¶
Специальная аннотация для явного объявления псевдонима типа.
Например:
from typing import TypeAlias Factors: TypeAlias = list[int]
TypeAliasособенно полезен в старых версиях Python для аннотирования псевдонимов, которые используют опережающие ссылки, поскольку анализаторам типов может быть трудно отличить их от обычных присваиваний переменных:from typing import Generic, TypeAlias, TypeVar T = TypeVar("T") # "Box" ещё не существует, # поэтому для прямой ссылки на Python <3.12 приходится использовать кавычки. # Использование ``TypeAlias`` сообщает тайпчекеру, что это объявление псевдонима типа, # а не присваивание переменной строкового значения. BoxOfStrings: TypeAlias = "Box[str]" class Box(Generic[T]): @classmethod def make_box_of_strings(cls) -> BoxOfStrings: ...
См. PEP 613 для получения дополнительных сведений.
Добавлено в версии 3.10.
Устарело с версии 3.12:
TypeAliasустарел в пользу инструкцииtype, которая создаёт экземплярыTypeAliasTypeи поддерживает опережающие ссылки изначально. Обратите внимание, что, хотяTypeAliasиTypeAliasTypeслужат похожим целям и имеют похожие названия, они различаются, и последний не является типом первого. УдалениеTypeAliasв настоящее время не планируется, но пользователям рекомендуется переходить на инструкцииtype.
Специальные формы¶Special forms
Их можно использовать в качестве типов в аннотациях. Они все поддерживают индексацию с помощью
[], но каждый из них имеет уникальный синтаксис.
- 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 # Конструктор на самом деле возвращает 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. См. выражения типов объединений.
- 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. См. выражения типов объединений.
- typing.Concatenate¶
Специальная форма для аннотирования функций высшего порядка.
Concatenateможет использоваться совместно с Callable иParamSpecдля аннотации вызываемого объекта высшего порядка, который добавляет, удаляет или преобразует параметры другого вызываемого объекта. Использование имеет формуConcatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable].Concatenateв настоящее время допустим только в качестве первого аргумента Callable. Последний параметрConcatenateдолжен бытьParamSpecили многоточием (...).Например, чтобы аннотировать декоратор
with_lock, который предоставляетthreading.Lockдекорируемой функции, можно использоватьConcatenate, чтобы указать, чтоwith_lockожидает вызываемый объект, который принимаетLockв качестве первого аргумента, и возвращает вызываемый объект с другой сигнатурой типа. В этом случаеParamSpecуказывает на то, что типы параметров возвращаемого вызываемого объекта зависят от типов параметров передаваемого вызываемого объекта:from collections.abc import Callable from threading import Lock from typing import Concatenate # Используйте эту блокировку, чтобы гарантировать, что только один поток выполняет функцию # в любой момент времени. my_lock = Lock() def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''Типобезопасный декоратор, предоставляющий блокировку.''' def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Передайте блокировку в качестве первого аргумента. return f(my_lock, *args, **kwargs) return inner @with_lock def sum_threadsafe(lock: Lock, numbers: list[float]) -> float: '''Складывайте список чисел потокобезопасным способом.''' with lock: return sum(numbers) # Нам не нужно передавать блокировку вручную благодаря декоратору. sum_threadsafe([1.1, 2.2, 3.3])
Добавлено в версии 3.10.
См. также
PEP 612 – Переменные спецификации параметров (PEP, в котором были введены
ParamSpecиConcatenate)Аннотация вызываемых объектовAnnotating callable objects
- typing.Literal¶
Специальная форма типизации для определения «литеральных типов».
Literalможно использовать, чтобы указать проверяющим типа, что аннотированный объект имеет значение, эквивалентное одному из предоставленных литералов.Например:
def validate_simple(data: Any) -> Literal[True]: # всегда возвращает True ... type 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.
Изменено в версии 3.9.1:
Literalтеперь дедуплицирует параметры. Сравнения на равенство объектовLiteralбольше не зависят от порядка. ОбъектыLiteralтеперь будут вызывать исключениеTypeErrorпри сравнении на равенство, если один из их параметров не является хешируемым.
- 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.Required¶
Специальная конструкция типизации для пометки ключа
TypedDictкак обязательного.В основном это полезно для
total=FalseTypedDict. Подробнее см.TypedDictи PEP 655.Добавлено в версии 3.12.
- typing.NotRequired¶
Специальная конструкция типизации для пометки ключа
TypedDictкак потенциально отсутствующего.Подробнее см.
TypedDictи PEP 655.Добавлено в версии 3.12.
- typing.Annotated¶
Специальная форма типизации для добавления контекстно-зависимых метаданных к аннотации.
Добавляет метаданные
xк заданному типуTс помощью аннотацииAnnotated[T, x]. Метаданные, добавленные с помощьюAnnotated, могут использоваться инструментами статического анализа или во время выполнения. Во время выполнения метаданные хранятся в атрибуте__metadata__.Если библиотека или инструмент встречает аннотацию
Annotated[T, x]и не имеет специальной логики для метаданных, он должен игнорировать метаданные и просто рассматривать аннотацию какT. Таким образом,Annotatedможет быть полезна для кода, который хочет использовать аннотации для целей, выходящих за рамки системы статической типизации Python.Использование
Annotated[T, x]в качестве аннотации по-прежнему допускает статическую проверку типов дляT, поскольку проверяющие типы просто игнорируют метаданныеx. Таким образом,Annotatedотличается от декоратора@no_type_check, который также можно использовать для добавления аннотаций за пределами системы типизации, но полностью отключает проверку типов для функции или класса.Ответственность за интерпретацию метаданных лежит на инструменте или библиотеке, встречающей аннотацию
Annotated. Инструмент или библиотека, встречающие типAnnotated, могут просмотреть элементы метаданных, чтобы определить, представляют ли они интерес (например, с помощьюisinstance()).- Annotated[<type>, <metadata>]
Вот пример того, как можно использовать
Annotatedдля добавления метаданных к аннотациям типов при выполнении анализа диапазонов:@dataclass class ValueRange: lo: int hi: int T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)]
Первый аргумент
Annotatedдолжен быть допустимым типом. Можно указать несколько элементов метаданных, так какAnnotatedподдерживает вариативные аргументы. Порядок элементов метаданных сохраняется и важен для проверок на равенство:@dataclass class ctype: kind: str a1 = Annotated[int, ValueRange(3, 10), ctype("char")] a2 = Annotated[int, ctype("char"), ValueRange(3, 10)] assert a1 != a2 # Порядок важен
Инструмент, потребляющий аннотации, сам решает, разрешено ли клиенту добавлять несколько элементов метаданных к одной аннотации и как объединять эти аннотации.
Вложенные типы
Annotatedуплощаются. Порядок элементов метаданных начинается с самой внутренней аннотации:assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ int, ValueRange(3, 10), ctype("char") ]
Дублирующиеся элементы метаданных не удаляются:
assert Annotated[int, ValueRange(3, 10)] != Annotated[ int, ValueRange(3, 10), ValueRange(3, 10) ]
Annotatedможно использовать с вложенными и обобщёнными псевдонимами:@dataclass class MaxLen: value: int type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)] # При использовании в аннотации типа тайпчекер будет обрабатывать "V" так же, как # ``Annotated[list[tuple[int, int]], MaxLen(10)]``: type V = Vec[int]
Annotatedнельзя использовать с распакованнымTypeVarTuple:type Variadic[*Ts] = Annotated[*Ts, Ann1] = Annotated[T1, T2, T3, ..., Ann1] # НЕДОПУСТИМО
где
T1,T2, … – этоTypeVars. Это недопустимо, поскольку в Annotated должен передаваться только один тип.По умолчанию
get_type_hints()удаляет метаданные из аннотаций. Передайтеinclude_extras=True, чтобы сохранить метаданные:>>> from typing import Annotated, get_type_hints >>> def func(x: Annotated[int, "metadata"]) -> None: pass ... >>> get_type_hints(func) {'x': <class 'int'>, 'return': <class 'NoneType'>} >>> get_type_hints(func, include_extras=True) {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}
Во время выполнения метаданные, связанные с типом
Annotated, можно получить через атрибут__metadata__:>>> from typing import Annotated >>> X = Annotated[int, "very", "important", "metadata"] >>> X typing.Annotated[int, 'very', 'important', 'metadata'] >>> X.__metadata__ ('very', 'important', 'metadata')
Чтобы получить исходный тип, обёрнутый
Annotated, используйте атрибут__origin__:>>> from typing import Annotated, get_origin >>> Password = Annotated[str, "secret"] >>> Password.__origin__ <class 'str'>
Обратите внимание, что использование
get_origin()вернёт самAnnotated:>>> get_origin(Password) <class 'typing.Annotated'>
См. также
- PEP 593 – Гибкие аннотации функций и переменных
PEP, вводящий
Annotatedв стандартную библиотеку.
Добавлено в версии 3.9.
- typing.TypeGuard¶
Специальная конструкция типов для пометки пользовательских функций-охранников типа.
TypeGuardможно использовать для аннотации возвращаемого типа пользовательской функции-охранника типа.TypeGuardпринимает только один аргумент типа. Во время выполнения функции, отмеченные таким образом, должны возвращать логическое значение.TypeGuardнаправлен на использование сужения типа – метода, используемого статическими проверками типов для определения более точного типа выражения в потоке кода программы. Обычно сужение типа выполняется путем анализа условного потока кода и применения сужения к блоку кода. Условное выражение в этом случае иногда называют «охранником типа»:def is_str(val: str | float): # защита типа "isinstance" if isinstance(val, str): # Тип ``val`` сужается до ``str`` ... else: # Иначе тип ``val`` сужается до ``float``. ...
Иногда бывает удобно использовать пользовательскую логическую функцию в качестве охранника типа. Такая функция должна использовать
TypeGuard[...]в качестве своего возвращаемого типа, чтобы предупредить статические проверки типов об этом намерении.Использование
-> TypeGuardсообщает статическому анализатору типов, что для данной функции:Возвращаемое значение – boolean.
Если возвращаемое значение –
True, то тип аргумента – это тип внутриTypeGuard.
Например:
def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Определяет, все ли объекты в списке являются строками''' return all(isinstance(x, str) for x in val) def func1(val: list[object]): if is_str_list(val): # Тип ``val`` сужается до ``list[str]``. print(" ".join(val)) else: # Тип ``val`` остаётся как ``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.
- typing.Unpack¶
Оператор typing для концептуальной пометки объекта как распакованного.
Например, использование оператора распаковки
*для кортежа переменных типа эквивалентно использованиюUnpack, чтобы пометить кортеж переменных типа как распакованный:Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Фактически делает: tup: tuple[Unpack[Ts]]
На самом деле,
Unpackи*можно использовать взаимозаменяемо в контексте типовtyping.TypeVarTupleиbuiltins.tuple. В старых версиях Python можно встретить явное использованиеUnpack, когда*нельзя было применять в определённых местах:# В старых версиях Python TypeVarTuple и Unpack # находятся в пакете обратной совместимости `typing_extensions`. from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Синтаксическая ошибка на Python <= 3.10! tup: tuple[Unpack[Ts]] # Семантически эквивалентно и обратно совместимо
Unpackтакже можно использовать вместе сtyping.TypedDictдля типизации**kwargsв сигнатуре функции:from typing import TypedDict, Unpack class Movie(TypedDict): name: str year: int # Эта функция ожидает два именованных аргумента: `name` типа `str` # и `year` типа `int`. def foo(**kwargs: Unpack[Movie]): ...
Подробнее об использовании
Unpackдля типизации**kwargsсм. в PEP 692.Добавлено в версии 3.12.
Построение обобщённых типов и псевдонимов типов¶Building generic types and type aliases
Следующие классы не следует использовать непосредственно в качестве аннотаций. Их предназначение – быть строительными блоками для создания обобщённых типов и псевдонимов типов.
Эти объекты можно создавать с помощью специального синтаксиса
(списки параметров типов и оператора type).
Для совместимости с Python 3.11 и более ранними версиями их также можно создавать
без специального синтаксиса, как описано ниже.
- class typing.Generic¶
Абстрактный базовый класс для обобщённых типов.
Обобщённый тип обычно объявляется добавлением списка параметров типа после имени класса:
class Mapping[KT, VT]: def __getitem__(self, key: KT) -> VT: ... # И т.д.
Такой класс неявно наследуется от
Generic. Семантика этого синтаксиса во время выполнения обсуждается в Справочнике по языку.Затем этот класс можно использовать следующим образом:
def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mapping[key] except KeyError: return default
Здесь квадратные скобки после имени функции указывают на обобщённую функцию.
Для обратной совместимости обобщённые классы также можно объявлять явным наследованием от
Generic. В этом случае параметры типа должны быть объявлены отдельно:KT = TypeVar('KT') VT = TypeVar('VT') class Mapping(Generic[KT, VT]): def __getitem__(self, key: KT) -> VT: ... # И т.д.
- class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False)¶
Переменная типа.
Предпочтительный способ создания переменной типа – специальный синтаксис для обобщённых функций, обобщённых классов и обобщённых псевдонимов типов:
class Sequence[T]: # T – это TypeVar ...
Этот синтаксис также можно использовать для создания переменных типа с границей и ограничениями:
class StrSequence[S: str]: # S – это TypeVar с верхней границей `str`; ... # можно сказать, что S "ограничен `str`" class StrOrBytesSequence[A: (str, bytes)]: # A – это TypeVar, ограниченный str или bytes ...
Однако при желании переиспользуемые переменные типа можно создавать и вручную, например так:
T = TypeVar('T') # Может быть чем угодно S = TypeVar('S', bound=str) # Может быть любым подтипом str A = TypeVar('A', str, bytes) # Должно быть ровно str или bytes
Переменные типа существуют в первую очередь для статических проверок типов. Они служат параметрами для обобщённых типов, а также для определений обобщённых функций и псевдонимов типов. Дополнительную информацию об обобщённых типах см. в
Generic. Обобщённые функции работают следующим образом:def repeat[T](x: T, n: int) -> Sequence[T]: """Возвращает список, содержащий n ссылок на x.""" return [x]*n def print_capitalized[S: str](x: S) -> S: """Печатает x с заглавной буквы и возвращает x.""" print(x.capitalize()) return x def concatenate[A: (str, bytes)](x: A, y: A) -> A: """Складывает две строки или два объекта bytes.""" return x + y
Обратите внимание, что переменные типа могут быть с границей, с ограничениями или ни с тем, ни с другим, но не могут быть одновременно и с границей, и с ограничениями.
Вариантность переменных типа выводится проверщиками типов, когда они создаются через синтаксис параметров типа или когда передаётся
infer_variance=True. Вручную созданные переменные типа могут быть явно помечены как ковариантные или контравариантные передачейcovariant=Trueилиcontravariant=True. По умолчанию вручную созданные переменные типа инвариантны. Подробнее см. в PEP 484 и PEP 695.Переменные типа с границей и с ограничениями имеют разную семантику в нескольких важных аспектах. Использование переменной типа с границей означает, что
TypeVarбудет выведен как наиболее конкретный возможный тип:x = print_capitalized('a string') reveal_type(x) # выявленный тип – str class StringSubclass(str): pass y = print_capitalized(StringSubclass('another string')) reveal_type(y) # раскрытый тип – StringSubclass z = print_capitalized(45) # ошибка: int не является подтипом str
Верхней границей переменной типа может быть конкретный тип, абстрактный тип (ABC или протокол) или даже объединение типов:
# Может быть чем угодно с методом __abs__ def print_abs[T: SupportsAbs](arg: T) -> None: print("Absolute value:", abs(arg)) U = TypeVar('U', bound=str|bytes) # Может быть любым подтипом объединения str|bytes V = TypeVar('V', bound=SupportsAbs) # Может быть чем угодно с методом __abs__
Однако использование переменной типа с ограничениями означает, что
TypeVarможет быть выведен только как один из заданных ограничений:a = concatenate('one', 'two') reveal_type(a) # выявленный тип – str b = concatenate(StringSubclass('one'), StringSubclass('two')) reveal_type(b) # выявленный тип – str, несмотря на то что передан StringSubclass c = concatenate('one', b'two') # ошибка: типовая переменная 'A' может быть либо str, либо bytes в вызове функции, но не обоими одновременно
Во время выполнения
isinstance(x, T)вызоветTypeError.- __name__¶
Имя переменной типа.
- __covariant__¶
Является ли переменная типа явно помеченной как ковариантная.
- __contravariant__¶
Является ли переменная типа явно помеченной как контравариантная.
- __infer_variance__¶
Должна ли вариативность переменной типа выводиться средствами проверки типов.
Добавлено в версии 3.12.
- __bound__¶
Верхняя граница переменной типа, если она задана.
Изменено в версии 3.12: Для переменных типа, созданных с помощью синтаксиса параметров типа, граница вычисляется только при обращении к атрибуту, а не при создании переменной типа (см. Ленивое вычисление).
- __constraints__¶
Кортеж, содержащий ограничения переменной типа, если они есть.
Изменено в версии 3.12: Для переменных типа, созданных с помощью синтаксиса параметров типа, ограничения вычисляются только при обращении к атрибуту, а не при создании переменной типа (см. Ленивое вычисление).
Изменено в версии 3.12: Переменные типа теперь можно объявлять с помощью синтаксиса параметров типа, введённого в PEP 695. Был добавлен параметр
infer_variance.
- class typing.TypeVarTuple(name)¶
Кортежная переменная типа. Специализированная форма переменной типа, которая позволяет использовать вариативные обобщения.
Кортежные переменные типа можно объявлять в списках параметров типа с помощью одной звёздочки (
*) перед именем:def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
Или явным вызовом конструктора
TypeVarTuple:T = TypeVar("T") Ts = TypeVarTuple("Ts") def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
Обычная переменная типа позволяет параметризацию одним типом. Кортежная переменная типа, напротив, позволяет параметризацию произвольным количеством типов, действуя как произвольное количество переменных типа, упакованных в кортеж. Например:
# T привязан к int, Ts привязан к () # Возвращаемое значение – (1,), тип которого tuple[int] move_first_element_to_last(tup=(1,)) # T привязан к int, Ts привязан к (str,) # Возвращаемое значение – ('spam', 1), тип которого tuple[str, int] move_first_element_to_last(tup=(1, 'spam')) # T привязан к int, Ts привязан к (str, float) # Возвращаемое значение – ('spam', 3.0, 1), тип которого tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) # Это не проходит проверку типов (и завершается ошибкой во время выполнения) # потому что tuple[()] несовместим с tuple[T, *Ts] # (требуется хотя бы один элемент) move_first_element_to_last(tup=())
Обратите внимание на использование оператора распаковки
*вtuple[T, *Ts]. Концептуально можно представитьTsкак кортеж переменных типа(T1, T2, ...). Тогдаtuple[T, *Ts]станетtuple[T, *(T1, T2, ...)], что эквивалентноtuple[T, T1, T2, ...]. (Обратите внимание, что в более старых версиях Python это могло быть записано с использованиемUnpack, например,Unpack[Ts].)Кортежные переменные типа всегда должны быть распакованы. Это помогает отличать кортежные переменные типа от обычных:
x: Ts # Недействительно x: tuple[Ts] # Недействительно x: tuple[*Ts] # Правильный способ сделать это
Кортежные переменные типа можно использовать в тех же контекстах, что и обычные переменные типа. Например, в определениях классов, аргументах и возвращаемых типах:
class Array[*Shape]: def __getitem__(self, key: tuple[*Shape]) -> float: ... def __abs__(self) -> "Array[*Shape]": ... def get_shape(self) -> tuple[*Shape]: ...
Кортежные переменные типа можно без проблем комбинировать с обычными переменными типа:
class Array[DType, *Shape]: # Это нормально pass class Array2[*Shape, DType]: # Это тоже нормально pass class Height: ... class Width: ... float_array_1d: Array[float, Height] = Array() # Совершенно нормально int_array_2d: Array[int, Height, Width] = Array() # Да, тоже нормально
Однако обратите внимание, что в одном списке аргументов типа или параметров типа может присутствовать не более одной кортежной переменной типа:
x: tuple[*Ts, *Ts] # Недействительно class Array[*Shape, *Shape]: # Недействительно pass
Наконец, распакованная кортежная переменная типа может использоваться в качестве аннотации типа для
*args:def call_soon[*Ts]( callback: Callable[[*Ts], None], *args: *Ts ) -> None: ... callback(*args)
В отличие от нераспакованных аннотаций
*args, например*args: int, которые указывают, что все аргументы имеют типint,*args: *Tsпозволяет ссылаться на типы отдельных аргументов в*args. Здесь это позволяет нам убедиться, что типы*args, передаваемых вcall_soon, соответствуют типам (позиционных) аргументовcallback.Подробнее о кортежах переменных типа см. в PEP 646.
- __name__¶
Имя кортежа переменных типа.
Добавлено в версии 3.12.
Changed in version 3.12: Type variable tuples can now be declared using the type parameter syntax introduced by PEP 695.
- class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False)¶
Переменная спецификации параметров. Специализированная версия переменных типа.
В списках параметров типа спецификации параметров можно объявлять с двумя звёздочками (
**):type IntFunc[**P] = Callable[P, int]
Для совместимости с Python 3.11 и более ранними версиями объекты
ParamSpecможно также создавать следующим образом:P = ParamSpec('P')
Переменные спецификации параметров существуют в первую очередь для статических проверок типов. Они используются для передачи типов параметров одного вызываемого объекта другому вызываемому объекту – шаблон, часто встречающийся в функциях высшего порядка и декораторах. Они допустимы только при использовании в
Concatenate, или как первый аргументCallable, или как параметры пользовательских обобщённых типов (Generics). См.Genericдля получения дополнительной информации об обобщённых типах.Например, чтобы добавить базовое логирование в функцию, можно создать декоратор
add_loggingдля логирования вызовов функций. Переменная спецификации параметров сообщает проверяющему типы, что вызываемый объект, переданный в декоратор, и новый вызываемый объект, возвращаемый им, имеют взаимозависимые параметры типа:from collections.abc import Callable import logging def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]: '''Типобезопасный декоратор для добавления логирования в функцию.''' 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: '''Складывает два числа.''' 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.
- __name__¶
Имя спецификации параметров.
Переменные спецификации параметров, созданные с помощью
covariant=Trueилиcontravariant=True, можно использовать для объявления ковариантных или контравариантных обобщённых типов. Аргументboundтакже принимается, как и вTypeVar. Однако фактическая семантика этих ключевых слов ещё не определена.Добавлено в версии 3.10.
Изменено в версии 3.12: Спецификации параметров теперь можно объявлять с помощью синтаксиса type parameter, введённого в PEP 695.
Примечание
Только переменные спецификации параметров, определённые в глобальной области видимости, могут быть pickled.
См. также
PEP 612 – Переменные спецификации параметров (PEP, в котором были введены
ParamSpecиConcatenate)Аннотация вызываемых объектовAnnotating callable objects
- typing.ParamSpecArgs¶
- typing.ParamSpecKwargs¶
Атрибуты аргументов и именованных аргументов (keyword arguments) объекта
ParamSpec. АтрибутP.argsобъектаParamSpecявляется экземпляромParamSpecArgs, аP.kwargs– экземпляромParamSpecKwargs. Они предназначены для интроспекции во время выполнения и не имеют особого значения для статических проверяющих типы.Вызов
get_origin()для любого из этих объектов вернёт исходныйParamSpec:>>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True >>> get_origin(P.kwargs) is P True
Добавлено в версии 3.10.
- class typing.TypeAliasType(name, value, *, type_params=())¶
Тип псевдонимов типов, созданных с помощью оператора
type.Пример:
>>> type Alias = int >>> type(Alias) <class 'typing.TypeAliasType'>
Добавлено в версии 3.12.
- __name__¶
Имя псевдонима типа:
>>> type Alias = int >>> Alias.__name__ 'Alias'
- __module__¶
Модуль, в котором был определён псевдоним типа:
>>> type Alias = int >>> Alias.__module__ '__main__'
- __type_params__¶
Параметры типа псевдонима типа или пустой кортеж, если псевдоним не является обобщённым (generic):
>>> type ListOrSet[T] = list[T] | set[T] >>> ListOrSet.__type_params__ (T,) >>> type NotGeneric = int >>> NotGeneric.__type_params__ ()
- __value__¶
Значение псевдонима типа. Оно вычисляется лениво, поэтому имена, используемые в определении псевдонима, не разрешаются до тех пор, пока не будет получен доступ к атрибуту
__value__:>>> type Mutually = Recursive >>> type Recursive = Mutually >>> Mutually Mutually >>> Recursive Recursive >>> Mutually.__value__ Recursive >>> Recursive.__value__ Mutually
Другие специальные директивы¶Other special directives
Эти функции и классы не следует использовать напрямую в качестве аннотаций. Их предназначение – быть строительными блоками для создания и объявления типов.
- 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): """Представляет сотрудника.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'
Подклассы
NamedTupleмогут быть обобщёнными (generic):class Group[T](NamedTuple): key: T group: list[T]
Обратно совместимое использование:
# Для создания обобщённого NamedTuple в Python 3.11 T = TypeVar("T") class Group(NamedTuple, Generic[T]): key: T group: list[T] # Также поддерживается функциональный синтаксис Employee = NamedTuple('Employee', [('name', str), ('id', int)])
Изменено в версии 3.6: Добавлена поддержка синтаксиса аннотации переменных PEP 526.
Изменено в версии 3.6.1: Добавлена поддержка значений по умолчанию, методов и строк документации.
Изменено в версии 3.8: Атрибуты
_field_typesи__annotations__теперь являются обычными словарями, а не экземплярамиOrderedDict.Изменено в версии 3.9: Атрибут
_field_typesудалён в пользу более стандартного атрибута__annotations__, который содержит ту же информацию.Изменено в версии 3.11: Добавлена поддержка обобщённых именованных кортежей (generic namedtuples).
- class typing.NewType(name, tp)¶
Вспомогательный класс для создания отдельных типов с низкими накладными расходами.
NewTypeсчитается отдельным типом для проверщика типов. Однако во время выполнения вызовNewTypeвозвращает свой аргумент без изменений.Использование:
UserId = NewType('UserId', int) # Объявить NewType "UserId" first_user = UserId(1) # "UserId" возвращает аргумент без изменений во время выполнения
- __module__¶
Модуль, в котором определён новый тип.
- __name__¶
Имя нового типа.
- __supertype__¶
Тип, на котором основан новый тип.
Добавлено в версии 3.5.2.
Изменено в версии 3.10:
NewTypeтеперь является классом, а не функцией.
- 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[T](Protocol): def meth(self) -> T: ...
В коде, который должен быть совместим с Python 3.11 или более старыми версиями, обобщённые протоколы можно записать следующим образом:
T = TypeVar("T") class GenProto(Protocol[T]): def meth(self) -> T: ...
Добавлено в версии 3.8.
- @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) @runtime_checkable class Named(Protocol): name: str import threading assert isinstance(threading.Thread(name='Bob'), Named)
Примечание
runtime_checkable()будет проверять только наличие требуемых методов или атрибутов, но не их сигнатуры типов или сами типы. Например,ssl.SSLObjectявляется классом, поэтому он проходит проверкуissubclass()на соответствие Callable. Однако методssl.SSLObject.__init__существует только для того, чтобы вызватьTypeErrorс более информативным сообщением, что делает невозможным вызов (создание экземпляра)ssl.SSLObject.Примечание
Проверка
isinstance()на соответствие протоколу с проверкой во время выполнения может быть удивительно медленной по сравнению с проверкойisinstance()для непротокольного класса. Рекомендуется использовать альтернативные идиомы, такие как вызовыhasattr()для структурных проверок в коде, чувствительном к производительности.Добавлено в версии 3.8.
Изменено в версии 3.12: Внутренняя реализация проверок
isinstance()на соответствие протоколам, проверяемым во время выполнения, теперь используетinspect.getattr_static()для поиска атрибутов (ранее использовалсяhasattr()). В результате некоторые объекты, которые ранее считались экземплярами проверяемого протокола, могут перестать считаться экземплярами этого протокола на Python 3.12+, и наоборот. Большинство пользователей вряд ли затронет это изменение.Изменено в версии 3.12: Члены протокола, проверяемого во время выполнения, теперь считаются «замороженными» во время выполнения сразу после создания класса. Модификация атрибутов такого протокола будет по-прежнему работать, но не повлияет на результаты проверок
isinstance(), сравнивающих объекты с этим протоколом. См. «Что нового в Python 3.12» для получения дополнительных сведений.
- 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')
Чтобы разрешить использование этой возможности в старых версиях Python, которые не поддерживают PEP 526,
TypedDictподдерживает две дополнительные эквивалентные синтаксические формы:Использование литерала
dictв качестве второго аргумента:Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
Использование именованных аргументов:
Point2D = TypedDict('Point2D', x=int, y=int, label=str)
Устарело с версии 3.11, будет удалено в версии 3.13: Синтаксис именованных аргументов устарел в 3.11 и будет удалён в 3.13. Он также может не поддерживаться статическими проверщиками типов.
Этот функциональный синтаксис позволяет определять ключи, которые не являются допустимыми идентификаторами, например, потому что они являются ключевыми словами или содержат дефисы, или когда имена ключей не должны быть искажены, как обычные закрытые имена:
# возбуждает SyntaxError class Point2D(TypedDict): in: int # 'in' – ключевое слово x-y: int # имя с дефисами class Definition(TypedDict): __schema: str # искажено до `_Definition__schema` # ОК, функциональный синтаксис Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) Definition = TypedDict('Definition', {'__schema': str}) # не искажается
По умолчанию все ключи должны присутствовать в
TypedDict. Можно пометить отдельные ключи как необязательные с помощьюNotRequired:class Point2D(TypedDict): x: int y: int label: NotRequired[str] # Альтернативный синтаксис Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})
Это означает, что
Point2DTypedDictможет не содержать ключlabel.Также можно по умолчанию пометить все ключи как необязательные, указав totality
False:class Point2D(TypedDict, total=False): x: int y: int # Альтернативный синтаксис Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)
Это означает, что
Point2DTypedDictможет не содержать любой из ключей. Средство проверки типов должно поддерживать только литералFalseилиTrueв качестве значения аргументаtotal.True– значение по умолчанию, и оно делает все элементы, определённые в теле класса, обязательными.Отдельные ключи
total=FalseTypedDictможно пометить как обязательные с помощьюRequired:class Point2D(TypedDict, total=False): x: Required[int] y: Required[int] label: str # Альтернативный синтаксис Point2D = TypedDict('Point2D', { 'x': Required[int], 'y': Required[int], 'label': str }, total=False)
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 # Класс, не являющийся TypedDict class XY(X, Y): pass # ОК class XZ(X, Z): pass # вызывает TypeError
TypedDictможет быть обобщённым:class Group[T](TypedDict): key: T group: list[T]
Чтобы создать обобщённый
TypedDict, совместимый с Python 3.11 и ниже, явно унаследуйтесь отGeneric:T = TypeVar("T") class Group(TypedDict, Generic[T]): key: T group: list[T]
TypedDictможет быть проанализирован с помощью словарей аннотаций (см. Лучшие практики работы с аннотациями для получения дополнительной информации о лучших практиках работы с аннотациями),__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
Этот атрибут отражает только значение аргумента
totalтекущего классаTypedDict, а не то, является ли класс семантически полным. Например,TypedDictс__total__, равнымTrue, может иметь ключи, помеченныеNotRequired, или наследоваться от другогоTypedDictсtotal=False. Поэтому для анализа обычно лучше использовать__required_keys__и__optional_keys__.
- __required_keys__¶
Добавлено в версии 3.9.
- __optional_keys__¶
Point2D.__required_keys__иPoint2D.__optional_keys__возвращают объектыfrozenset, содержащие обязательные и необязательные ключи соответственно.Ключи, помеченные
Required, всегда будут появляться в__required_keys__, а ключи, помеченныеNotRequired, всегда будут появляться в__optional_keys__.Для обратной совместимости с Python 3.10 и ниже также можно использовать наследование для объявления как обязательных, так и необязательных ключей в одном
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.
Примечание
Если используется
from __future__ import annotationsили аннотации заданы в виде строк, аннотации не вычисляются при определенииTypedDict. Поэтому анализ во время выполнения, на который полагаются__required_keys__и__optional_keys__, может работать неправильно, и значения атрибутов могут быть неверными.
Смотрите PEP 589 для дополнительных примеров и подробных правил использования
TypedDict.Добавлено в версии 3.8.
Изменено в версии 3.11: Добавлена поддержка пометки отдельных ключей как
RequiredилиNotRequired. См. PEP 655.Изменено в версии 3.11: Добавлена поддержка обобщённых
TypedDict.
Протоколы¶Protocols
Следующие протоколы предоставляются модулем typing. Все они декорированы
@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__ковариантным по возвращаемому типу.
Абстрактные базовые классы для работы с IO¶ABCs for working with IO
Функции и декораторы¶Functions and decorators
- typing.cast(typ, val)¶
Приводит значение к типу.
Это возвращает значение без изменений. Для проверщика типов это сигнализирует, что возвращаемое значение имеет указанный тип, но во время выполнения мы намеренно ничего не проверяем (мы хотим, чтобы это было как можно быстрее).
- typing.assert_type(val, typ, /)¶
Запросить у статического проверщика типов подтверждение, что val имеет выведенный тип typ.
Во время выполнения эта функция ничего не делает: она возвращает первый аргумент без изменений, без проверок или побочных эффектов, независимо от фактического типа аргумента.
Когда статический проверщик типов встречает вызов
assert_type(), он выдает ошибку, если значение не относится к указанному типу:def greet(name: str) -> None: assert_type(name, str) # ОК, выведенный тип `name` – `str` assert_type(name, int) # ошибка проверки типов
Эта функция полезна для проверки того, что понимание скрипта проверщиком типов соответствует намерениям разработчика:
def complex_function(arg: object): # Выполнить сложную логику сужения типа, # после чего ожидается, что выведенный тип станет `int` ... # Проверить, правильно ли проверщик типов понимает нашу функцию assert_type(arg, int)
Добавлено в версии 3.12.
- typing.assert_never(arg, /)¶
Попросить статический проверщик типов подтвердить, что строка кода недостижима.
Пример:
def int_or_str(arg: int | str) -> None: match arg: case int(): print("It's an int") case str(): print("It's a str") case _ as unreachable: assert_never(unreachable)
Здесь аннотации позволяют проверщику типов вывести, что последний случай никогда не выполнится, поскольку
argявляется либоint, либоstr, и оба варианта уже покрыты предыдущими случаями.Если проверщик типов обнаружит, что вызов
assert_never()достижим, он выдаст ошибку. Например, если бы аннотация типа дляargвместо этого былаint | str | float, проверщик типов выдал бы ошибку, указывающую, чтоunreachableимеет типfloat. Для того чтобы вызовassert_neverпрошел проверку типов, выведенный тип переданного аргумента должен быть нижним типомNeverи ничем иным.Во время выполнения эта функция выбрасывает исключение при вызове.
См. также
В разделе Unreachable Code and Exhaustiveness Checking содержится дополнительная информация о проверке полноты с помощью статической типизации.
Добавлено в версии 3.12.
- typing.reveal_type(obj, /)¶
Попросить статический проверщик типов показать выведенный тип выражения.
Когда статический проверщик типов встречает вызов этой функции, он выдает диагностическое сообщение с выведенным типом аргумента. Например:
x: int = 1 reveal_type(x) # Раскрытый тип – "builtins.int"
Это может быть полезно для отладки того, как проверщик типов обрабатывает конкретный фрагмент кода.
Во время выполнения эта функция выводит тип аргумента во время выполнения в
sys.stderrи возвращает аргумент без изменений (что позволяет использовать вызов внутри выражения):x = reveal_type(1) # выводит «Runtime type is int» print(x) # выводит "1"
Обратите внимание, что тип во время выполнения может отличаться от статически выведенного типа (быть более или менее конкретным).
Большинство проверщиков типов поддерживают
reveal_type()в любом месте, даже если имя не импортировано изtyping. Однако импорт имени изtypingпозволяет коду выполняться без ошибок времени выполнения и более четко выражает намерения.Добавлено в версии 3.12.
- @typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)¶
Декоратор для пометки объекта как предоставляющего поведение, подобное
dataclass.dataclass_transformможет использоваться для декорирования класса, метакласса или функции, которая сама является декоратором. Наличие@dataclass_transform()сообщает статическому проверщику типов, что декорированный объект выполняет во время выполнения «магию», преобразующую класс аналогично@dataclasses.dataclass.Пример использования с функцией-декоратором:
@dataclass_transform() def create_model[T](cls: type[T]) -> type[T]: ... return cls @create_model class CustomerModel: id: int name: str
На базовом классе:
@dataclass_transform() class ModelBase: ... class CustomerModel(ModelBase): id: int name: str
На метаклассе:
@dataclass_transform() class ModelMeta(type): ... class ModelBase(metaclass=ModelMeta): ... class CustomerModel(ModelBase): id: int name: str
Классы
CustomerModel, определенные выше, будут обрабатываться проверщиками типов аналогично классам, созданным с помощью@dataclasses.dataclass. Например, проверщики типов будут предполагать, что эти классы имеют методы__init__, которые принимаютidиname.Декорированный класс, метакласс или функция могут принимать следующие булевы аргументы, которые, как будет считать проверщик типов, имеют тот же эффект, что и для декоратора
@dataclasses.dataclass:init,eq,order,unsafe_hash,frozen,match_args,kw_onlyиslots. Значения этих аргументов (TrueилиFalse) должны быть статически вычислимыми.Аргументы декоратора
dataclass_transformмогут использоваться для настройки поведения по умолчанию декорированного класса, метакласса или функции:- Параметры:
eq_default (bool) – Указывает, предполагается ли параметр
eqравнымTrueилиFalse, если он опущен вызывающей стороной. По умолчаниюTrue.order_default (bool) – Указывает, предполагается ли параметр
orderравнымTrueилиFalse, если он опущен вызывающей стороной. По умолчаниюFalse.kw_only_default (bool) – Указывает, предполагается ли параметр
kw_onlyравнымTrueилиFalse, если он опущен вызывающей стороной. По умолчаниюFalse.frozen_default (bool) –
Указывает, считается ли параметр
frozenравнымTrueилиFalse, если он опущен вызывающей стороной. По умолчаниюFalse.Добавлено в версии 3.12.
field_specifiers (tuple[Callable[..., Any], ...]) – Задаёт статический список поддерживаемых классов или функций, описывающих поля, аналогично
dataclasses.field(). По умолчанию().**kwargs (Any) – Допускаются произвольные другие именованные аргументы, чтобы обеспечить возможность будущих расширений.
Проверщики типов распознают следующие необязательные параметры в спецификаторах полей:
Распознанные параметры для спецификаторов полей¶ Имя параметра
Описание
initУказывает, должно ли поле быть включено в синтезируемый метод
__init__. Если не указано,initпо умолчанию равноTrue.defaultПредоставляет значение по умолчанию для поля.
default_factoryПредоставляет колбэк времени выполнения, возвращающий значение по умолчанию для поля. Если не указаны ни
default, ниdefault_factory, считается, что поле не имеет значения по умолчанию, и при создании экземпляра класса для него должно быть предоставлено значение.factoryПсевдоним для параметра
default_factoryв спецификаторах полей.kw_onlyУказывает, должно ли поле быть помечено как keyword-only. Если
True, поле будет keyword-only. ЕслиFalse, оно не будет keyword-only. Если не указано, будет использовано значение параметраkw_onlyобъекта, декорированного с помощьюdataclass_transform, или, если оно не указано, значениеkw_only_defaultнаdataclass_transform.aliasПредоставляет альтернативное имя для поля. Это альтернативное имя используется в синтезируемом методе
__init__.Во время выполнения этот декоратор записывает свои аргументы в атрибут
__dataclass_transform__декорированного объекта. Других эффектов во время выполнения нет.Подробнее см. PEP 681.
Добавлено в версии 3.12.
- @typing.overload¶
Декоратор для создания перегруженных функций и методов.
Декоратор
@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): ... # здесь находится фактическая реализация
Подробнее и сравнение с другими семантиками типизации см. PEP 484.
Изменено в версии 3.11: Перегруженные функции теперь можно интроспектировать во время выполнения с помощью
get_overloads().
- typing.get_overloads(func)¶
Возвращает последовательность определений, декорированных
@overload, для func.func – это объект функции для реализации перегруженной функции. Например, если дано определение
processв документации для@overload,get_overloads(process)вернёт последовательность из трёх объектов функций для трёх определённых перегрузок. Если вызвана для функции без перегрузок,get_overloads()возвращает пустую последовательность.get_overloads()можно использовать для интроспекции перегруженной функции во время выполнения.Добавлено в версии 3.12.
- typing.clear_overloads()¶
Очищает все зарегистрированные перегрузки во внутреннем реестре.
Это можно использовать для освобождения памяти, занятой реестром.
Добавлено в версии 3.12.
- @typing.final¶
Декоратор для указания окончательных методов и окончательных классов.
Декорирование метода с помощью
@finalуказывает проверщику типов, что метод не может быть переопределён в подклассе. Декорирование класса с помощью@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.
Изменено в версии 3.11: Декоратор теперь будет пытаться установить атрибут
__final__в значениеTrueна декорированном объекте. Таким образом, проверку видаif getattr(obj, "__final__", False)можно использовать во время выполнения, чтобы определить, был ли объектobjпомечен как окончательный (final). Если декорированный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключения.
- @typing.no_type_check¶
Декоратор, указывающий, что аннотации не являются подсказками типов.
Это работает как декоратор класса или функции. Для класса он применяется рекурсивно ко всем методам и классам, определённым в этом классе (но не к методам, определённым в его суперклассах или подклассах). Средства проверки типов будут игнорировать все аннотации в функции или классе с этим декоратором.
@no_type_checkизменяет декорированный объект на месте.
- @typing.no_type_check_decorator¶
Декоратор, придающий другому декоратору эффект
no_type_check().Он оборачивает декоратор чем-то, что оборачивает декорированную функцию в
no_type_check().
- @typing.override¶
Декоратор, указывающий, что метод в подклассе предназначен для переопределения метода или атрибута в суперклассе.
Средства проверки типов должны выдавать ошибку, если метод, декорированный
@override, на самом деле ничего не переопределяет. Это помогает предотвратить ошибки, которые могут возникнуть, когда базовый класс изменяется без соответствующего изменения в дочернем классе.Например:
class Base: def log_status(self) -> None: ... class Sub(Base): @override def log_status(self) -> None: # ОК: переопределяет Base.log_status ... @override def done(self) -> None: # Ошибка, выдаваемая проверщиком типов ...
Проверка этого свойства во время выполнения не производится.
Декоратор будет пытаться установить атрибут
__override__в значениеTrueна декорированном объекте. Таким образом, проверку видаif getattr(obj, "__override__", False)можно использовать во время выполнения, чтобы определить, был ли объектobjпомечен как переопределение. Если декорированный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключения.См. PEP 698 для получения дополнительных сведений.
Добавлено в версии 3.12.
- @typing.type_check_only¶
Декоратор для пометки класса или функции как недоступных во время выполнения.
Сам этот декоратор недоступен во время выполнения. Он в основном предназначен для пометки классов, определённых в файлах заглушек типов (type stub), если реализация возвращает экземпляр закрытого класса:
@type_check_only class Response: # приватный или недоступный во время выполнения code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
Обратите внимание, что возврат экземпляров закрытых классов не рекомендуется. Обычно предпочтительнее делать такие классы открытыми.
Вспомогательные функции для интроспекции¶Introspection helpers
- typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False)¶
Возвращает словарь, содержащий аннотации типов для функции, метода, модуля или объекта класса.
Часто это то же самое, что и
obj.__annotations__, но эта функция вносит следующие изменения в словарь аннотаций:Прямые ссылки (forward references), закодированные как строковые литералы или объекты
ForwardRef, обрабатываются путём вычисления их в пространствах имён globalns, localns и (где применимо) пространстве имён obj’s параметра типа. Если globalns или localns не заданы, соответствующие словари пространств имён выводятся из obj.Noneзаменяется наtypes.NoneType.Если к obj был применён
@no_type_check, возвращается пустой словарь.Если obj – это класс
C, функция возвращает словарь, который объединяет аннотации из базовых классовCс теми, что указаны непосредственно вC. Это делается путём обходаC.__mro__и последовательного объединения словарей__annotations__. Аннотации классов, расположенных раньше в порядке разрешения методов, всегда имеют приоритет над аннотациями классов, расположенных позже в порядке разрешения методов.Функция рекурсивно заменяет все вхождения
Annotated[T, ...]наT, если только include_extras не равенTrue(см.Annotatedдля получения дополнительной информации).
См. также
inspect.get_annotations()– функция более низкого уровня, которая возвращает аннотации более напрямую.Примечание
Если какие-либо прямые ссылки (forward references) в аннотациях obj не могут быть разрешены или не являются валидным кодом Python, эта функция вызовет исключение
NameError. Например, это может произойти с импортированными псевдонимами типов, содержащими прямые ссылки, или с именами, импортированными черезif TYPE_CHECKING.Изменено в версии 3.9: Добавлен параметр
include_extrasв рамках PEP 593. См. документацию поAnnotatedдля получения дополнительных сведений.Изменено в версии 3.11: Ранее
Optional[t]добавлялась для аннотаций функций и методов, если было установлено значение по умолчанию, равноеNone. Теперь аннотация возвращается без изменений.
- typing.get_origin(tp)¶
Возвращает неиндексированную версию типа: для объекта typing вида
X[Y, Z, ...]возвращаетX.Если
X– это псевдоним из модуля typing для встроенного класса или классаcollections, он будет нормализован до исходного класса. ЕслиXявляется экземпляромParamSpecArgsилиParamSpecKwargs, возвращается базовыйParamSpec. Для неподдерживаемых объектов возвращаетсяNone.Примеры:
assert get_origin(str) is None assert get_origin(Dict[str, int]) is dict assert get_origin(Union[int, str]) is Union assert get_origin(Annotated[str, "metadata"]) is Annotated P = ParamSpec('P') assert get_origin(P.args) is P assert get_origin(P.kwargs) is P
Добавлено в версии 3.8.
- typing.get_args(tp)¶
Возвращает аргументы типа после выполнения всех подстановок: для объекта typing вида
X[Y, Z, ...]возвращает(Y, Z, ...).Если
Xявляется объединением (union) илиLiteralсодержится в другом обобщённом типе, порядок(Y, Z, ...)может отличаться от порядка исходных аргументов[Y, Z, ...]из-за кеширования типов. Для неподдерживаемых объектов возвращается().Примеры:
assert get_args(int) == () assert get_args(Dict[int, str]) == (int, str) assert get_args(Union[int, str]) == (int, str)
Добавлено в версии 3.8.
- typing.is_typeddict(tp)¶
Проверяет, является ли тип
TypedDict.Например:
class Film(TypedDict): title: str year: int assert is_typeddict(Film) assert not is_typeddict(list | str) # TypedDict – это фабрика для создания типизированных словарей, # а не сам типизированный словарь assert not is_typeddict(TypedDict)
Добавлено в версии 3.10.
- class typing.ForwardRef¶
Класс для внутреннего представления строковых прямых ссылок в typing.
Например,
List["SomeClass"]неявно преобразуется вList[ForwardRef("SomeClass")].ForwardRefне должен создаваться пользователем, но может использоваться инструментами интроспекции.Примечание
обобщённые типы PEP 585, такие как
list["SomeClass"], не будут неявно преобразовываться вlist[ForwardRef("SomeClass")]и, следовательно, не будут автоматически разрешаться вlist[SomeClass].Добавлено в версии 3.7.4.
Константа¶Constant
- 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от интерпретатора во время выполнения. Аннотации типов для локальных переменных не вычисляются, поэтому вторую аннотацию не нужно заключать в кавычки.Примечание
Если используется
from __future__ import annotations, аннотации не вычисляются во время определения функции. Вместо этого они сохраняются как строки в__annotations__. Это избавляет от необходимости заключать аннотацию в кавычки (см. PEP 563).Добавлено в версии 3.5.2.
Устаревшие псевдонимы¶Deprecated aliases
Этот модуль определяет несколько устаревших псевдонимов для уже существующих классов стандартной библиотеки. Изначально они были включены в модуль typing для поддержки параметризации этих обобщённых классов с помощью []. Однако эти псевдонимы стали избыточными в Python 3.9, когда соответствующие существующие классы были расширены для поддержки [] (см. PEP 585).
Избыточные типы считаются устаревшими начиная с Python 3.9. Однако, хотя псевдонимы могут быть удалены в какой-то момент, их удаление в настоящее время не планируется. Поэтому в настоящее время интерпретатор не выдаёт предупреждений об устаревании для этих псевдонимов.
Если в какой-то момент будет принято решение удалить эти устаревшие псевдонимы, интерпретатор будет выдавать предупреждение об устаревании как минимум за два релиза до удаления. Псевдонимы гарантированно останутся в модуле typing без предупреждений об устаревании как минимум до Python 3.14.
Проверяющим типы рекомендуется отмечать использование устаревших типов, если проверяемая программа нацелена на минимальную версию Python 3.9 или новее.
Псевдонимы встроенных типов¶Aliases to built-in types
- class typing.Dict(dict, MutableMapping[KT, VT])¶
Устаревший псевдоним
dict.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
Mapping, а неdictилиtyping.Dict.Deprecated since version 3.9:
builtins.dictnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.List(list, MutableSequence[T])¶
Устаревший псевдоним
list.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
SequenceилиIterable, а неlistилиtyping.List.Deprecated since version 3.9:
builtins.listnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Set(set, MutableSet[T])¶
Устаревший псевдоним
builtins.set.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
collections.abc.Set, а неsetилиtyping.Set.Deprecated since version 3.9:
builtins.setnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.FrozenSet(frozenset, AbstractSet[T_co])¶
Устаревший псевдоним
builtins.frozenset.Deprecated since version 3.9:
builtins.frozensetnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- typing.Tuple¶
Устаревший псевдоним для
tuple.tupleиTupleявляются особыми случаями в системе типов; см. Аннотирование кортежей для получения дополнительной информации.Deprecated since version 3.9:
builtins.tuplenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Type(Generic[CT_co])¶
Устаревший псевдоним
type.См. Тип объектов класса для подробностей об использовании
typeилиtyping.Typeв аннотациях типов.Добавлено в версии 3.5.2.
Deprecated since version 3.9:
builtins.typenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
Псевдонимы типов в collections¶Aliases to types in collections
- class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])¶
Устаревший псевдоним
collections.defaultdict.Добавлено в версии 3.5.2.
Deprecated since version 3.9:
collections.defaultdictnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])¶
Устаревший псевдоним
collections.OrderedDict.Добавлено в версии 3.7.2.
Deprecated since version 3.9:
collections.OrderedDictnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])¶
Устаревший псевдоним
collections.ChainMap.Добавлено в версии 3.6.1.
Deprecated since version 3.9:
collections.ChainMapnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Counter(collections.Counter, Dict[T, int])¶
Устаревший псевдоним
collections.Counter.Добавлено в версии 3.6.1.
Deprecated since version 3.9:
collections.Counternow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Deque(deque, MutableSequence[T])¶
Устаревший псевдоним
collections.deque.Добавлено в версии 3.6.1.
Deprecated since version 3.9:
collections.dequenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
Псевдонимы для других конкретных типов¶Aliases to other concrete types
Устарело с версии 3.8, будет удалено в версии 3.13: Пространство имён
typing.ioустарело и будет удалено. Эти типы следует импортировать напрямую изtyping.
- class typing.Pattern¶
- class typing.Match¶
Устаревшие псевдонимы, соответствующие типам возвращаемых значений из
re.compile()иre.match().Эти типы (и соответствующие функции) являются обобщёнными относительно
AnyStr.Patternможет быть специализирован какPattern[str]илиPattern[bytes];Matchможет быть специализирован какMatch[str]илиMatch[bytes].Устарело с версии 3.8, будет удалено в версии 3.13: Пространство имён
typing.reустарело и будет удалено. Эти типы следует импортировать напрямую изtyping.Устарело с версии 3.9: Классы
PatternиMatchизreтеперь поддерживают[]. См. PEP 585 и Generic Alias Type.
- class typing.Text¶
Устаревший псевдоним для
str.Textпредоставляется для обеспечения совместимости с кодом 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.
Устарело с версии 3.11: Python 2 больше не поддерживается, и большинство проверщиков типов также больше не поддерживают проверку типов для кода Python 2. Удаление псевдонима в настоящее время не планируется, но пользователям рекомендуется использовать
strвместоText.
Псевдонимы для контейнерных ABC в collections.abc¶Aliases to container ABCs in collections.abc
- class typing.AbstractSet(Collection[T_co])¶
Устаревший псевдоним
collections.abc.Set.Deprecated since version 3.9:
collections.abc.Setnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.ByteString(Sequence[int])¶
Этот тип представляет типы
bytes,bytearrayиmemoryviewпоследовательностей байтов.Устарело с версии 3.9, будет удалено в версии 3.14: Предпочтительнее использовать
collections.abc.Bufferили объединение наподобиеbytes | bytearray | memoryview.
- class typing.Collection(Sized, Iterable[T_co], Container[T_co])¶
Устаревший псевдоним
collections.abc.Collection.Добавлено в версии 3.6.
Deprecated since version 3.9:
collections.abc.Collectionnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Container(Generic[T_co])¶
Устаревший псевдоним
collections.abc.Container.Deprecated since version 3.9:
collections.abc.Containernow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])¶
Устаревший псевдоним
collections.abc.ItemsView.Deprecated since version 3.9:
collections.abc.ItemsViewnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.KeysView(MappingView, AbstractSet[KT_co])¶
Устаревший псевдоним
collections.abc.KeysView.Deprecated since version 3.9:
collections.abc.KeysViewnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Mapping(Collection[KT], Generic[KT, VT_co])¶
Устаревший псевдоним
collections.abc.Mapping.Deprecated since version 3.9:
collections.abc.Mappingnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.MappingView(Sized)¶
Устаревший псевдоним
collections.abc.MappingView.Deprecated since version 3.9:
collections.abc.MappingViewnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.MutableMapping(Mapping[KT, VT])¶
Устаревший псевдоним
collections.abc.MutableMapping.Deprecated since version 3.9:
collections.abc.MutableMappingnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.MutableSequence(Sequence[T])¶
Устаревший псевдоним
collections.abc.MutableSequence.Deprecated since version 3.9:
collections.abc.MutableSequencenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.MutableSet(AbstractSet[T])¶
Устаревший псевдоним
collections.abc.MutableSet.Deprecated since version 3.9:
collections.abc.MutableSetnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Sequence(Reversible[T_co], Collection[T_co])¶
Устаревший псевдоним
collections.abc.Sequence.Deprecated since version 3.9:
collections.abc.Sequencenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.ValuesView(MappingView, Collection[_VT_co])¶
Устаревший псевдоним
collections.abc.ValuesView.Deprecated since version 3.9:
collections.abc.ValuesViewnow supports subscripting ([]). See PEP 585 and Generic Alias Type.
Псевдонимы для асинхронных ABC в collections.abc¶Aliases to asynchronous ABCs in collections.abc
- class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])¶
Устаревший псевдоним
collections.abc.Coroutine.See Annotating generators and coroutines for details on using
collections.abc.Coroutineandtyping.Coroutinein type annotations.Добавлено в версии 3.5.3.
Deprecated since version 3.9:
collections.abc.Coroutinenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])¶
Устаревший псевдоним
collections.abc.AsyncGenerator.See Annotating generators and coroutines for details on using
collections.abc.AsyncGeneratorandtyping.AsyncGeneratorin type annotations.Добавлено в версии 3.6.1.
Deprecated since version 3.9:
collections.abc.AsyncGeneratornow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.AsyncIterable(Generic[T_co])¶
Устаревший псевдоним
collections.abc.AsyncIterable.Добавлено в версии 3.5.2.
Deprecated since version 3.9:
collections.abc.AsyncIterablenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.AsyncIterator(AsyncIterable[T_co])¶
Устаревший псевдоним
collections.abc.AsyncIterator.Добавлено в версии 3.5.2.
Deprecated since version 3.9:
collections.abc.AsyncIteratornow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Awaitable(Generic[T_co])¶
Устаревший псевдоним
collections.abc.Awaitable.Добавлено в версии 3.5.2.
Deprecated since version 3.9:
collections.abc.Awaitablenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
Псевдонимы для других ABC в collections.abc¶Aliases to other ABCs in collections.abc
- class typing.Iterable(Generic[T_co])¶
Устаревший псевдоним
collections.abc.Iterable.Deprecated since version 3.9:
collections.abc.Iterablenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Iterator(Iterable[T_co])¶
Устаревший псевдоним
collections.abc.Iterator.Deprecated since version 3.9:
collections.abc.Iteratornow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- typing.Callable¶
Устаревший псевдоним
collections.abc.Callable.See Annotating callable objects for details on how to use
collections.abc.Callableandtyping.Callablein type annotations.Deprecated since version 3.9:
collections.abc.Callablenow supports subscripting ([]). See PEP 585 and Generic Alias Type.Changed in version 3.10:
Callablenow supportsParamSpecandConcatenate. See PEP 612 for more details.
- class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])¶
Устаревший псевдоним
collections.abc.Generator.See Annotating generators and coroutines for details on using
collections.abc.Generatorandtyping.Generatorin type annotations.Deprecated since version 3.9:
collections.abc.Generatornow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Hashable¶
Устаревший псевдоним
collections.abc.Hashable.Устарело с версии 3.12: Используйте непосредственно
collections.abc.Hashable.
- class typing.Reversible(Iterable[T_co])¶
Устаревший псевдоним
collections.abc.Reversible.Deprecated since version 3.9:
collections.abc.Reversiblenow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.Sized¶
Устаревший псевдоним
collections.abc.Sized.Устарело с версии 3.12: Используйте непосредственно
collections.abc.Sized.
Псевдонимы для contextlib ABCs¶Aliases to contextlib ABCs
- class typing.ContextManager(Generic[T_co])¶
Устаревший псевдоним
contextlib.AbstractContextManager.Добавлено в версии 3.5.4.
Deprecated since version 3.9:
contextlib.AbstractContextManagernow supports subscripting ([]). See PEP 585 and Generic Alias Type.
- class typing.AsyncContextManager(Generic[T_co])¶
Устаревший псевдоним
contextlib.AbstractAsyncContextManager.Добавлено в версии 3.6.2.
Deprecated since version 3.9:
contextlib.AbstractAsyncContextManagernow supports subscripting ([]). See PEP 585 and Generic Alias Type.
Хронология устаревания основных возможностей¶Deprecation Timeline of Major Features
Некоторые возможности в typing устарели и могут быть удалены в будущей версии Python. Для удобства ниже приведена таблица с основными устаревшими элементами. Она может изменяться, и в ней перечислены не все устаревшие возможности.
Возможность |
Устарело в |
Планируемое удаление |
PEP/issue |
|---|---|---|---|
|
3.8 |
3.13 |
|
|
3.9 |
Не определено (см. устаревшие псевдонимы для дополнительной информации) |
|
3.9 |
3.14 |
||
3.11 |
Не определено |
||
3.12 |
Не определено |
||
3.12 |
Не определено |