typing — Поддержка подсказок типов
Добавлена в версии 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).
- Раздел «Справочник по системе типов» в документации mypy
-
Система типов Python стандартизована через PEP, поэтому эта справка должна в целом относиться к большинству проверяющих типов Python. (Некоторые части могут быть специфичными для mypy.)
- “Статическая типизация с Python”
-
Независимая от проверяющего инструмента документация, написанная сообществом, описывающая функции системы типов, полезные инструменты для работы с подсказками типов и лучшие практики для использования подсказок типов.
Спецификация системы типов Python
Каноническая, актуальная спецификация системы типов Python доступна на “Спецификация системы типов Python”.
Псевдонимы типов
Псевдоним типа определяется с помощью инструкции type, которая создаёт экземпляр TypeAliasType. В данном примере, Vector и list[float] будут обрабатываться как эквивалентные статическими проверяющими типами:
type Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# passes type checking; a list of floats qualifies as a 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:
...
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
message: str,
servers: Sequence[tuple[tuple[str, int], dict[str, str]]]
) -> None:
...
Инструкция 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:
...
# passes type checking
user_a = get_user_name(UserId(42351))
# fails type checking; an int is not a UserId
user_b = get_user_name(-1)
Вы по-прежнему можете выполнять все int операции с переменной типа UserId, но результат всегда будет типа int. Это позволяет передавать UserId туда, где ожидается int, но предотвратит случайное создание UserId неверным способом:
# 'output' is of type 'int', not 'UserId' output = UserId(23413) + UserId(54341)
Обратите внимание, что эти проверки выполняются только статическим проверяющим типом. Во время выполнения оператор Derived = NewType('Derived', Base) сделает Derived вызываемым объектом, который немедленно возвращает переданный ему параметр. Это означает, что выражение Derived(some_value) не создаёт новый класс и не вносит значительной дополнительной нагрузки помимо обычного вызова функции.
Более точно, выражение some_value is Derived(some_value) всегда истинно во время выполнения.
Недопустимо создавать подтип Derived:
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not pass type checking
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.
Аннотирование вызываемых объектов
Функции — или другие вызываемые объекты — могут быть аннотированы с помощью collections.abc.Callable или typing.Callable. Callable[[int], str] обозначает функцию, принимающую один параметр типа int и возвращающую str.
Например:
from collections.abc import Callable, Awaitable
def feeder(get_next_item: Callable[[], str]) -> None:
... # Body
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
... # Body
async def on_update(value: str) -> None:
... # Body
callback: Callable[[str], Awaitable[None]] = on_update
Синтаксис подписки всегда должен использоваться ровно с двумя значениями: списком аргументов и типом возвращаемого значения. Список аргументов должен быть списком типов, ParamSpec, Concatenate или многоточием. Возвращаемый тип должен быть единственным типом.
Если в качестве списка аргументов задан литеральный многоточие ..., это указывает, что вызываемый объект с любым произвольным списком параметров был бы приемлем:
def concat(x: str, y: str) -> str:
return x + y
x: Callable[..., str]
x = str # OK
x = concat # Also OK
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) # OK
batch_proc([], bad_cb) # Error! Argument 2 has incompatible type because of
# different name and kind in the callback
Вызываемые объекты, принимающие другие вызываемые объекты в качестве аргументов, могут указывать зависимость типов параметров друг от друга с помощью ParamSpec. Кроме того, если такой вызываемый объект добавляет или удаляет аргументы из других вызываемых объектов, может быть использован оператор Concatenate. Они имеют вид Callable[ParamSpecVariable, ReturnType] и Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType] соответственно.
Изменено в версии 3.10: Callable теперь поддерживает ParamSpec и Concatenate. Подробнее см. PEP 612.
См. также
Документация по ParamSpec и Concatenate содержит примеры использования в Callable.
Обобщенные типы
Поскольку информация о типе объектов, хранящихся в контейнерах, не может быть статически выведена обобщенным способом, многие классы контейнеров в стандартной библиотеке поддерживают подписку для обозначения ожидаемых типов элементов контейнера.
from collections.abc import Mapping, Sequence
class Employee: ...
# Sequence[Employee] indicates that all elements in the sequence
# must be instances of "Employee".
# Mapping[str, str] indicates that all keys and all values in the mapping
# must be strings.
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
Обобщенные функции и классы могут быть параметризованы с помощью синтаксиса параметров типа синтаксиса параметров типа:
from collections.abc import Sequence
def first[T](l: Sequence[T]) -> T: # Function is generic over the TypeVar "T"
return l[0]
Или с помощью фабрики TypeVar непосредственно:
from collections.abc import Sequence
from typing import TypeVar
U = TypeVar('U') # Declare type variable "U"
def second(l: Sequence[U]) -> U: # Function is generic over the TypeVar "U"
return l[1]
Изменено в версии 3.12: Синтаксическая поддержка обобщенных типов появилась в Python 3.12.
Аннотация кортежей
Для большинства контейнеров в Python система типов предполагает, что все элементы контейнера будут одного типа. Например:
from collections.abc import Mapping
# Type checker will infer that all elements in ``x`` are meant to be ints
x: list[int] = []
# Type checker error: ``list`` only accepts a single type argument:
y: list[int, str] = [1, 'foo']
# Type checker will infer that all keys in ``z`` are meant to be strings,
# and that all values in ``z`` are meant to be either strings or ints
z: Mapping[str, str | int] = {}
list принимает только один аргумент типа, поэтому система проверки типов выдаст ошибку при y присваивании выше. Аналогично, Mapping принимает только два аргумента типа: первый указывает тип ключей, а второй — тип значений.
В отличие от большинства других контейнеров Python, в типичном Python-коде кортежи часто содержат элементы разных типов. По этой причине кортежи являются особым случаем в системе типов Python. tuple принимает любое количество аргументов типа:
# OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int x: tuple[int] = (5,) # OK: ``y`` is assigned to a tuple of length 2; # element 1 is an int, element 2 is a str y: tuple[int, str] = (5, "foo") # Error: the type annotation indicates a tuple of length 1, # but ``z`` has been assigned to a tuple of length 3 z: tuple[int] = (1, 2, 3)
Чтобы обозначить кортеж любой длины, в котором все элементы имеют одинаковый тип T, используйте tuple[T, ...]. Чтобы обозначить пустой кортеж, используйте tuple[()]. Использование простого tuple в качестве аннотации эквивалентно использованию tuple[Any, ...]:
x: tuple[int, ...] = (1, 2)
# These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
x = (1, 2, 3)
x = ()
# This reassignment is an error: all elements in ``x`` must be ints
x = ("foo", "bar")
# ``y`` can only ever be assigned to an empty tuple
y: tuple[()] = ()
z: tuple = ("foo", "bar")
# These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
z = (1, 2, 3)
z = ()
Тип объектов класса
Переменная, аннотированная с помощью C может принимать значение типа C. В отличие от этого, переменная, аннотированная с помощью type[C] (или typing.Type[C]), может принимать значения, являющиеся сами классами — в частности, она будет принимать объект класса C. Например:
a = 3 # Has type ``int`` b = int # Has type ``type[int]`` c = type(a) # Also has type ``type[int]``
Обратите внимание, что type[C] является ковариативным:
class User: ...
class ProUser(User): ...
class TeamUser(User): ...
def make_new_user(user_class: type[User]) -> User:
# ...
return user_class()
make_new_user(User) # OK
make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
make_new_user(TeamUser) # Still fine
make_new_user(User()) # Error: expected ``type[User]`` but got ``User``
make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]``
Единственными допустимыми параметрами для type являются классы, Any, переменные типа и объединения любого из этих типов. Например:
def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
new_non_team_user(BasicUser) # OK
new_non_team_user(ProUser) # OK
new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype
# of ``type[BasicUser | ProUser]``
new_non_team_user(User) # Also an error
type[Any] эквивалентно type, который является корнем иерархии метаклассов Python.
Пользовательские обобщенные типы
Пользовательский класс может быть определен как обобщенный класс.
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): # Same as Iterable[Any]
...
Также поддерживаются псевдонимы обобщенных типов, определенные пользователем. Примеры:
from collections.abc import Iterable
type Response[S] = Iterable[S] | int
# Return type here is same as 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: # Same as 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 is a TypeVar; P is a 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
Особым видом типа является Any. Статический проверяющий типов будет считать каждый тип совместимым с Any и Any совместимыми с каждым типом.
Это означает, что можно выполнить любую операцию или вызов метода над значением типа Any и присвоить его любой переменной:
from typing import Any
a: Any = None
a = [] # OK
a = 2 # OK
s: str = ''
s = a # OK
def foo(item: Any) -> int:
# Passes type checking; 'item' could be any type,
# and that type might have a 'bar' method
item.bar()
...
Обратите внимание, что никакая проверка типов не выполняется при присвоении значения типа Any более точному типу. Например, статический проверяющий типов не выдал ошибку при присвоении a переменной s, хотя s была объявлена как тип str и в ходе выполнения получает значение типа int!
Кроме того, все функции без типа возвращаемого значения или типов параметров будут по умолчанию использовать Any:
def legacy_parser(text):
...
return data
# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
...
return data
Это поведение позволяет использовать Any в качестве «спасательного круга», когда необходимо смешать динамически и статически типизированный код.
Сравните поведение Any с поведением object. Подобно Any, каждый тип является подтипом object. Однако, в отличие от Any, обратное неверно: object не является подтипом всех остальных типов.
Это означает, что когда тип значения — object, проверяющий типов отклонит почти все операции над ним, и присвоение его переменной (или использование его как возвращаемого значения) более специализированного типа — это ошибка типизации. Например:
def hash_a(item: object) -> int:
# Fails type checking; an object does not have a 'magic' method.
item.magic()
...
def hash_b(item: Any) -> int:
# Passes type checking
item.magic()
...
# Passes type checking, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")
# Passes type checking, since Any is compatible with all types
hash_b(42)
hash_b("foo")
Используйте object для указания того, что значение может быть любого типа безопасным способом. Используйте Any для указания того, что значение имеет динамическую типизацию.
Номинальная против структурной типизации
Изначально PEP 484 определял систему статической типизации Python как использующую номинальную типизацию. Это означает, что класс A разрешен там, где ожидается класс B только в том случае, если A является подклассом B.
Это требование ранее также применялось к абстрактным базовым классам, таким как Iterable. Проблема с этим подходом заключается в том, что класс должен быть явно помечен для поддержки этих классов, что нетипично для динамически типизированного Python. Например, это соответствует PEP 484:
from collections.abc import Sized, Iterable, Iterator
class Bucket(Sized, Iterable[int]):
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
PEP 544 позволяет решить эту проблему, позволяя пользователям писать код выше без явных базовых классов в определении класса, что позволяет Bucket неявно считаться подтипом как Sized, так и Iterable[int] статическими проверяющими типов. Это известно как структурная типизация (или статическая утиная типизация):
from collections.abc import Iterator, Iterable
class Bucket: # Note: no base classes
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Passes type check
Кроме того, наследовав специальный класс Protocol, пользователь может определять новые пользовательские протоколы, чтобы полностью использовать структурную типизацию (см. примеры ниже).
Содержание модуля
Модуль typing определяет следующие классы, функции и декораторы.
Специальные примитивы типизации
Специальные типы
Их можно использовать в качестве типов в аннотациях. Они не поддерживают подписку с использованием [].
-
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, output has type 'str' concat(b"foo", b"bar") # OK, output has type 'bytes' concat("foo", b"bar") # Error, cannot mix str and bytesОбратите внимание, что, несмотря на своё название,
AnyStrне имеет ничего общего с типомAnyи не означает «любой строковый тип». В частности,AnyStrиstr | bytesотличаются друг от друга и имеют различные области применения:# Invalid use of AnyStr: # The type variable is used only once in the function signature, # so cannot be "solved" by the type checker def greet_bad(cond: bool) -> AnyStr: return "hi there!" if cond else b"greetings!" # The better way of annotating this function: 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") # OK run_query(literal_string) # OK run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" )LiteralStringполезен для чувствительных API, где произвольные строки, сгенерированные пользователем, могут привести к проблемам. Например, два вышеуказанных случая, которые генерируют ошибки проверки типа, могут быть уязвимы для атаки SQL-инъекции.См. PEP 675 для получения дополнительных сведений.
Добавлен в версии 3.11.
-
typing.Never -
typing.NoReturn -
NeverиNoReturnпредставляют собой тип-дно, тип, не имеющий членов.Они могут использоваться для обозначения того, что функция никогда не возвращает значение, например,
sys.exit():from typing import Never # or NoReturn def stop() -> Never: raise RuntimeError('no way')Или для определения функции, которая никогда не должна вызываться, так как нет допустимых аргументов, таких как
assert_never():from typing import Never # or NoReturn def never_call_me(arg: Never) -> None: pass def int_or_str(arg: int | str) -> None: never_call_me(arg) # type checker error match arg: case int(): print("It's an int") case str(): print("It's a str") case _: never_call_me(arg) # OK, arg is of type Never (or 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()) # Revealed type is "Foo" reveal_type(SubclassOfFoo().return_self()) # Revealed type is "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 would be an incorrect return annotation here, # as the object returned is always an instance of Eggs, # even in subclasses def returns_eggs(self) -> "Eggs": return Eggs()См. PEP 673 для получения дополнительных сведений.
Добавлен в версии 3.11.
-
-
typing.TypeAlias -
Специальная аннотация для явного объявления псевдонима типа.
Например:
from typing import TypeAlias Factors: TypeAlias = list[int]
TypeAliasособенно полезна в старых версиях Python для аннотирования псевдонимов, использующих вперёд объявления, так как проверка типов может с трудом отличить их от обычных присваиваний переменных:from typing import Generic, TypeAlias, TypeVar T = TypeVar("T") # "Box" does not exist yet, # so we have to use quotes for the forward reference on Python <3.12. # Using ``TypeAlias`` tells the type checker that this is a type alias declaration, # not a variable assignment to a string. BoxOfStrings: TypeAlias = "Box[str]" class Box(Generic[T]): @classmethod def make_box_of_strings(cls) -> BoxOfStrings: ...См. PEP 613 для получения дополнительных сведений.
Устарело начиная с версии 3.12:
TypeAliasустарело в пользу оператораtype, который создаёт экземплярыTypeAliasTypeи который нативно поддерживает вперёд объявления. Обратите внимание, что, хотяTypeAliasиTypeAliasTypeслужат похожим целям и имеют аналогичные имена, они различны, и последний не является типом первого. УдалениеTypeAliasв настоящее время не планируется, но пользователям рекомендуется перейти к операторамtype.
Специальные формы
Эти формы могут быть использованы в качестве типов в аннотациях. Все они поддерживают подписку с использованием [], но каждая имеет уникальный синтаксис.
-
typing.Union -
Тип объединения;
Union[X, Y]эквивалентноX | Yи означает либо X, либо Y.Для определения объединения используйте, например,
Union[int, str]или сокращенную записьint | str. Использование сокращенной записи рекомендуется. Подробности:- Аргументы должны быть типами, и их должно быть по крайней мере один.
-
Объединения объединений сжимаются, например:
Union[Union[int, str], float] == Union[int, str, float]
-
Объединения с одним аргументом исчезают, например:
Union[int] == int # The constructor actually returns int
-
Избыточные аргументы пропускаются, например:
Union[int, str, int] == Union[int, str] == int | str
-
При сравнении объединений порядок аргументов игнорируется, например:
Union[int, str] == Union[str, int]
- Вы не можете наследоваться от или создавать экземпляры
Union. - Вы не можете записать
Union[X][Y].
Изменено в версии 3.7: Явных подклассов из объединений не удаляется во время выполнения.
Изменено в версии 3.10: Теперь объединения могут быть записаны как
X | Y. См. выражения типа объединения.
-
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 # Use this lock to ensure that only one thread is executing a function # at any time. my_lock = Lock() def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''A type-safe decorator which provides a lock.''' def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. return f(my_lock, *args, **kwargs) return inner @with_lock def sum_threadsafe(lock: Lock, numbers: list[float]) -> float: '''Add a list of numbers together in a thread-safe manner.''' with lock: return sum(numbers) # We don't need to pass in the lock ourselves thanks to the decorator. sum_threadsafe([1.1, 2.2, 3.3])Добавлен в версии 3.10.
См. также
-
PEP 612 — Переменные для спецификации параметров (PEP, который представил
ParamSpecиConcatenate) ParamSpec- Аннотирование вызываемых объектов
-
PEP 612 — Переменные для спецификации параметров (PEP, который представил
-
typing.Literal -
Специальная форма типизации для определения «литеральных типов».
Literalможет использоваться для указания проверкам типов, что аннотированный объект имеет значение, эквивалентное одному из предоставленных литералов.Например:
def validate_simple(data: Any) -> Literal[True]: # always returns True ... type Mode = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: Mode) -> str: ... open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checkerLiteral[...]не может быть подклассом. Во время выполнения любое значение разрешается в качестве аргумента типа дляLiteral[...], но проверки типов могут накладывать ограничения. См. PEP 586 для получения дополнительной информации о литеральных типах.Добавлен в версии 3.8.
-
typing.ClassVar -
Специальный конструктор типа для маркировки переменных класса.
Как введено в PEP 526, аннотация переменной, обернутая в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен устанавливаться для экземпляров этого класса. Использование:
class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variableClassVarпринимает только типы и не может быть далее подписываемым.ClassVarне является классом сам по себе и не должен использоваться сisinstance()илиissubclass().ClassVarне изменяет поведение Python во время выполнения, но может использоваться сторонними проверками типов. Например, проверка типов может отметить следующий код как ошибку:enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OKДобавлен в версии 3.5.3.
-
typing.Final -
Специальный конструктор типа для указания конечных имен для проверок типов.
Конечные имена не могут быть переопределены ни в одном из областей видимости. Конечные имена, объявленные в областях видимости класса, не могут быть переопределены в подклассах.
Например:
MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Error reported by type checker class Connection: TIMEOUT: Final[int] = 10 class FastConnector(Connection): TIMEOUT = 1 # Error reported by type checkerПроверки этих свойств во время выполнения нет. См. PEP 591 для получения дополнительной информации.
Добавлен в версии 3.8.
-
typing.Annotated -
Специальная форма типизации для добавления метаданных, специфичных для контекста, к аннотации.
Добавьте метаданные
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 Annotated[int, ValueRange(3, 10), ctype("char")]Инструменту, потребляющему аннотации, решать, разрешено ли клиенту добавлять несколько элементов метаданных к одной аннотации и как объединять эти аннотации.
-
Annotatedдолжен быть с индексами как минимум из двух аргументов (Annotated[int]недействительно) -
Порядок элементов метаданных сохраняется и имеет значение для проверок на равенство:
assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ int, ctype("char"), ValueRange(3, 10) ] -
Вложенные типы
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)] # When used in a type annotation, a type checker will treat "V" the same as # ``Annotated[list[tuple[int, int]], MaxLen(10)]``: type V = Vec[int] -
Annotatedнельзя использовать с распакованнымTypeVarTuple:type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid
Это эквивалентно:
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')
См. также
- PEP 593 - Гибкие аннотации функций и переменных
-
PEP, который вводит
Annotatedв стандартную библиотеку.
Добавлен в версии 3.9.
-
typing.TypeGuard -
Специальная конструкция типизации для маркировки пользовательских функций-предикатов типа.
TypeGuardможет использоваться для аннотации возвращаемого типа пользовательской функции-предиката типа.TypeGuardпринимает только один аргумент типа. Во время выполнения функции, помеченные таким образом, должны возвращать булево значение.TypeGuardпризван принести пользу сужению типов — технике, используемой инструментами статической типизации для определения более точного типа выражения в потоке кода программы. Обычно сужение типов выполняется путем анализа условного потока кода и применения сужения к блоку кода. Условное выражение в этом случае иногда называется «предикатом типа»:def is_str(val: str | float): # "isinstance" type guard if isinstance(val, str): # Type of ``val`` is narrowed to ``str`` ... else: # Else, type of ``val`` is narrowed to ``float``. ...Иногда бывает удобно использовать пользовательскую булеву функцию в качестве предиката типа. Такая функция должна использовать
TypeGuard[...]в качестве типа возвращаемого значения, чтобы сообщить инструментам статической типизации об этом намерении.Использование
-> TypeGuardсообщает инструменту статической типизации, что для данной функции:- Возвращаемое значение — булево.
- Если возвращаемое значение —
True, тип его аргумента — тип внутриTypeGuard.
Например:
def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Determines whether all objects in the list are strings''' return all(isinstance(x, str) for x in val) def func1(val: list[object]): if is_str_list(val): # Type of ``val`` is narrowed to ``list[str]``. print(" ".join(val)) else: # Type of ``val`` remains as ``list[object]``. print("Not a list of strings!")Если
is_str_list— метод класса или экземпляра, то тип вTypeGuardсоответствует типу второго параметра (послеclsилиself).Короче говоря, форма
def foo(arg: TypeA) -> TypeGuard[TypeB]: ..., означает, что еслиfoo(arg)возвращаетTrue, тоargсужается отTypeAдоTypeB.Примечание
TypeBне обязательно должен быть более узкой формойTypeA— он может быть даже более широкой. Основная причина заключается в том, чтобы разрешить такие вещи, как сужениеlist[object]доlist[str]даже если последнее не является подтипом первого, так какlistинвариантен. Ответственность за написание безопасных с точки зрения типов предикатов типа возлагается на пользователя.TypeGuardтакже работает с переменными типов. См. PEP 647 для получения дополнительных сведений.Добавлен в версии 3.10.
-
typing.Unpack -
Оператор типизации для концептуальной маркировки объекта как распакованного.
Например, использование оператора распаковки
*на кортеже переменной типа эквивалентно использованиюUnpackдля обозначения кортежа переменной типа как распакованного:Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Effectively does: tup: tuple[Unpack[Ts]]На самом деле,
Unpackможет использоваться взаимозаменяемо с*в контекстеtyping.TypeVarTupleиbuiltins.tupleтипов. Вы можете увидетьUnpackв явном виде в более ранних версиях Python, где*нельзя было использовать в определенных местах:# In older versions of Python, TypeVarTuple and Unpack # are located in the `typing_extensions` backports package. from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Syntax error on Python <= 3.10! tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatibleUnpackтакже можно использовать вместе сtyping.TypedDictдля типизации**kwargsв сигнатуре функции:from typing import TypedDict, Unpack class Movie(TypedDict): name: str year: int # This function expects two keyword arguments - `name` of type `str` # and `year` of type `int`. def foo(**kwargs: Unpack[Movie]): ...См. PEP 692 для получения более подробной информации об использовании
Unpackдля типизации**kwargs.Добавлен в версии 3.11.
Создание обобщенных типов и псевдонимов типов
Следующие классы не должны использоваться напрямую в качестве аннотаций. Их предназначение — служить строительными блоками для создания обобщенных типов и псевдонимов типов.
Эти объекты могут быть созданы с помощью специальной синтаксической конструкции (списки параметров типа и оператора type). Для совместимости с Python 3.11 и более ранними версиями их также можно создавать без специального синтаксиса, как описано ниже.
-
class typing.Generic -
Абстрактный базовый класс для обобщенных типов.
Обобщенный тип обычно объявляется путем добавления списка параметров типа после имени класса:
class Mapping[KT, VT]: def __getitem__(self, key: KT) -> VT: ... # Etc.Такой класс неявно наследуется от
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: ... # Etc.
-
class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False) -
Переменная типа.
Предпочтительный способ создания переменной типа — использование специального синтаксиса для обобщенных функций, обобщенных классов и обобщенных псевдонимов типов:
class Sequence[T]: # T is a TypeVar ...Этот синтаксис также можно использовать для создания ограниченных и связанных переменных типа:
class StrSequence[S: str]: # S is a TypeVar bound to str ... class StrOrBytesSequence[A: (str, bytes)]: # A is a TypeVar constrained to str or bytes ...Однако, если это необходимо, повторно используемые переменные типа также можно создать вручную, как показано ниже:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytesПеременные типа в первую очередь предназначены для статических проверок типов. Они служат параметрами для обобщенных типов, а также для определений обобщенных функций и псевдонимов типов. Дополнительную информацию об обобщенных типах см. в
Generic. Обобщенные функции работают следующим образом:def repeat[T](x: T, n: int) -> Sequence[T]: """Return a list containing n references to x.""" return [x]*n def print_capitalized[S: str](x: S) -> S: """Print x capitalized, and return x.""" print(x.capitalize()) return x def concatenate[A: (str, bytes)](x: A, y: A) -> A: """Add two strings or bytes objects together.""" return x + yОбратите внимание, что переменные типа могут быть связанными, ограниченными или ни тем, ни другим, но не могут быть одновременно связанными и ограниченными.
Изменчивость переменных типа определяется проверяющими типами при их создании с помощью синтаксиса параметров типа или при передаче
infer_variance=True. Вручную созданные переменные типа могут быть явно отмечены как ковариантные или контравариантные путем передачиcovariant=Trueилиcontravariant=True. По умолчанию вручную созданные переменные типа являются инвариантными. См. PEP 484 и PEP 695 для получения более подробной информации.Связанные и ограниченные переменные типа имеют разную семантику во многих важных аспектах. Использование связанной переменной типа означает, что
TypeVarбудет решаться с использованием наиболее конкретного возможного типа:x = print_capitalized('a string') reveal_type(x) # revealed type is str class StringSubclass(str): pass y = print_capitalized(StringSubclass('another string')) reveal_type(y) # revealed type is StringSubclass z = print_capitalized(45) # error: int is not a subtype of strПеременные типа могут быть связаны с конкретными типами, абстрактными типами (ABC или протоколами), а также с объединениями типов:
# Can be anything with an __abs__ method def print_abs[T: SupportsAbs](arg: T) -> None: print("Absolute value:", abs(arg)) U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ methodИспользование ограниченной переменной типа, однако, означает, что
TypeVarможет быть решено только как один из заданных ограничений:a = concatenate('one', 'two') reveal_type(a) # revealed type is str b = concatenate(StringSubclass('one'), StringSubclass('two')) reveal_type(b) # revealed type is str, despite StringSubclass being passed in c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not bothВо время выполнения
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 is bound to int, Ts is bound to () # Return value is (1,), which has type tuple[int] move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,) # Return value is ('spam', 1), which has type tuple[str, int] move_first_element_to_last(tup=(1, 'spam')) # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) # This fails to type check (and fails at runtime) # because tuple[()] is not compatible with tuple[T, *Ts] # (at least one element is required) 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 # Not valid x: tuple[Ts] # Not valid x: tuple[*Ts] # The correct way to do it
Кортежи переменных типа можно использовать в тех же контекстах, что и обычные переменные типа. Например, в определениях классов, аргументах и типах возвращаемых значений:
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]: # This is fine pass class Array2[*Shape, DType]: # This would also be fine pass class Height: ... class Width: ... float_array_1d: Array[float, Height] = Array() # Totally fine int_array_2d: Array[int, Height, Width] = Array() # Yup, fine tooОднако обратите внимание, что в одном списке аргументов или параметров типа может быть только один кортеж переменных типа:
x: tuple[*Ts, *Ts] # Not valid class Array[*Shape, *Shape]: # Not valid 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.11.
Изменено в версии 3.12: Кортежи переменных типа теперь можно объявлять с использованием синтаксиса параметра типа, введенного в 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, или в качестве параметров для пользовательских обобщений. См.Genericдля получения дополнительной информации о обобщённых типах.Например, для добавления базовой регистрации в функцию можно создать декоратор
add_loggingдля регистрации вызовов функций. Переменная спецификации параметра сообщает инструменту проверки типов, что вызываемый объект, переданный в декоратор, и новый вызываемый объект, возвращаемый им, имеют взаимозависимые параметры типа:from collections.abc import Callable import logging def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]: '''A type-safe decorator to add logging to a function.''' def inner(*args: P.args, **kwargs: P.kwargs) -> T: logging.info(f'{f.__name__} was called') return f(*args, **kwargs) return inner @add_logging def add_two(x: float, y: float) -> float: '''Add two numbers together.''' return x + yБез
ParamSpec, самый простой способ аннотировать это ранее заключался в использованииTypeVarс ограничениемCallable[..., Any]. Однако это вызывает две проблемы:- Инструмент проверки типов не может проверить функцию
inner, потому что*argsи**kwargsдолжны быть типизированы какAny. -
cast()может потребоваться в теле декоратораadd_loggingпри возвращении функцииinner, или инструменту статической проверки типов нужно сказать игнорироватьreturn inner.
-
args
-
kwargs -
Поскольку
ParamSpecзахватывает как позиционные, так и ключевые параметры,P.argsиP.kwargsмогут быть использованы для разделенияParamSpecна компоненты.P.argsпредставляет собой кортеж позиционных параметров в данном вызове и должен использоваться только для аннотации*args.P.kwargsпредставляет собой отображение ключевых параметров и их значений в данном вызове и должно использоваться только для аннотации**kwargs. Оба атрибута требуют, чтобы аннотируемый параметр был в области видимости. Во время выполнения,P.argsиP.kwargsявляются соответственно экземплярамиParamSpecArgsиParamSpecKwargs.
-
__name__ -
Имя спецификации параметра.
Переменные спецификации параметров, созданные с помощью
covariant=Trueилиcontravariant=Trueмогут быть использованы для объявления ковариативных или контравариативных обобщенных типов. Также принимается аргументbound, аналогичноTypeVar. Однако фактическая семантика этих ключевых слов ещё не определена.Добавлен в версии 3.10.
Изменено в версии 3.12: Спецификации параметров теперь можно объявлять с использованием синтаксиса параметра типа, введённого в PEP 695.
Примечание
Только переменные спецификации параметров, определённые в глобальной области, могут быть сериализованы.
См. также
-
PEP 612 — Переменные спецификации параметров (PEP, введший
ParamSpecиConcatenate) Concatenate- Аннотирование вызываемых объектов
- Инструмент проверки типов не может проверить функцию
-
typing.ParamSpecArgs -
typing.ParamSpecKwargs -
Атрибуты аргументов и ключевых аргументов
ParamSpec. АтрибутP.argsParamSpecявляется экземпляром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__ -
Параметры типа псевдонима, или пустой кортеж, если псевдоним не обобщённый:
>>> 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
-
Другие специальные директивы
Эти функции и классы не должны использоваться напрямую как аннотации. Их предназначение — быть строительными блоками для создания и объявления типов.
-
class typing.NamedTuple -
Набранная версия
collections.namedtuple().Использование:
class Employee(NamedTuple): name: str id: intЭто эквивалентно:
Employee = collections.namedtuple('Employee', ['name', 'id'])Чтобы присвоить полю значение по умолчанию, можно присвоить ему значение в теле класса:
class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') assert employee.id == 3Поля со значением по умолчанию должны следовать за полями без значения по умолчанию.
Полученный класс имеет дополнительный атрибут
__annotations__, содержащий словарь, сопоставляющий имена полей с типами полей. (Имена полей находятся в атрибуте_fields, а значения по умолчанию — в атрибуте_field_defaults, оба из которых являются частью APInamedtuple().)NamedTupleподклассы также могут иметь строки документации и методы:class Employee(NamedTuple): """Represents an employee.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'NamedTupleподклассы могут быть обобщёнными:class Group[T](NamedTuple): key: T group: list[T]Обратно совместимое использование:
# For creating a generic NamedTuple on Python 3.11 or lower class Group(NamedTuple, Generic[T]): key: T group: list[T] # A functional syntax is also supported 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: Добавлена поддержка обобщённых кортежей с именованными полями.
-
class typing.NewType(name, tp) -
Вспомогательный класс для создания типов отдельных типов с низкими накладными расходами.
Тип
NewTypeсчитается типом отдельного типа в проверяющем типе. Однако при выполнении вызовNewTypeвозвращает свой аргумент без изменений.Использование:
UserId = NewType('UserId', int) # Declare the NewType "UserId" first_user = UserId(1) # "UserId" returns the argument unchanged at runtime-
__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()) # Passes static type checkСм. 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при применении к классу, не являющемуся протоколом. Это позволяет выполнить простую структурную проверку, очень похожую на «хитрости» в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'} # OK b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')Для возможности использования этой функции со старыми версиями Python, не поддерживающими PEP 526,
TypedDictподдерживает две дополнительные эквивалентные синтаксические формы:-
Использование литерального
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. Он также может не поддерживаться статическими средствами проверки типов.
Функциональный синтаксис также следует использовать, когда любой из ключей не является допустимым идентификатором, например, потому что это ключевые слова или содержат дефисы. Пример:
# raises SyntaxError class Point2D(TypedDict): in: int # 'in' is a keyword x-y: int # name with hyphens # OK, functional syntax Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})По умолчанию все ключи должны быть присутствовать в
TypedDict. Можно отметить отдельные ключи как необязательные, используяNotRequired:class Point2D(TypedDict): x: int y: int label: NotRequired[str] # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})Это означает, что у
Point2DTypedDictможет быть опущен ключlabel.Также можно помечать все ключи как необязательные по умолчанию, указав полную совокупность
False:class Point2D(TypedDict, total=False): x: int y: int # Alternative syntax 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 # Alternative syntax Point2D = TypedDict('Point2D', { 'x': Required[int], 'y': Required[int], 'label': str }, total=False)Тип
TypedDictможет наследоваться от одного или нескольких других типовTypedDictс использованием синтаксиса на основе классов. Использование:class Point3D(Point2D): z: intPoint3Dимеет три элемента:x,yиz. Это эквивалентно этому определению:class Point3D(TypedDict): x: int y: int z: intTypedDictне может наследоваться от не-TypedDictкласса, за исключениемGeneric. Например:class X(TypedDict): x: int class Y(TypedDict): y: int class Z(object): pass # A non-TypedDict class class XY(X, Y): pass # OK class XZ(X, Z): pass # raises TypeErrorTypedDictможет быть дженериком: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. -
Протоколы
Следующие протоколы предоставляются модулем 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__, ковариативный по типу возвращаемого значения.
ABC для работы с IO
-
class typing.IO -
class typing.TextIO -
class typing.BinaryIO -
Обобщённый тип
IO[AnyStr]и его подклассыTextIO(IO[str])иBinaryIO(IO[bytes])представляют типы потоков ввода-вывода, таких как возвращаемые функциейopen().
Функции и декораторы
-
typing.cast(typ, val) -
Преобразование значения к типу.
Это возвращает значение без изменений. Для анализатора типов это означает, что возвращаемое значение имеет назначенный тип, но во время выполнения мы намеренно ничего не проверяем (мы хотим, чтобы это было максимально быстро).
-
typing.assert_type(val, typ, /) -
Запрос статическому анализатору типов подтвердить, что val имеет выведенный тип typ.
Во время выполнения это ничего не делает: возвращает первый аргумент без изменений без проверок или побочных эффектов, независимо от фактического типа аргумента.
Когда статический анализатор типов сталкивается с вызовом
assert_type(), он генерирует ошибку, если значение не соответствует указанному типу:def greet(name: str) -> None: assert_type(name, str) # OK, inferred type of `name` is `str` assert_type(name, int) # type checker errorЭта функция полезна для обеспечения соответствия понимания анализатора типов сценарию намерения разработчика:
def complex_function(arg: object): # Do some complex type-narrowing logic, # after which we hope the inferred type will be `int` ... # Test whether the type checker correctly understands our function assert_type(arg, int)Добавлена в версии 3.11.
-
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.11.
-
typing.reveal_type(obj, /) -
Запрос статическому анализатору типов раскрыть выведенный тип выражения.
Когда статический анализатор типов сталкивается с вызовом этой функции, он генерирует диагностику с выведенным типом аргумента. Например:
x: int = 1 reveal_type(x) # Revealed type is "builtins.int"
Это может быть полезно, когда вы хотите отладить, как ваш анализатор типов обрабатывает конкретный фрагмент кода.
Во время выполнения эта функция печатает тип аргумента во время выполнения в
sys.stderrи возвращает аргумент без изменений (что позволяет использовать вызов в выражении):x = reveal_type(1) # prints "Runtime type is int" print(x) # prints "1"
Обратите внимание, что тип во время выполнения может отличаться от (быть более или менее конкретным, чем) статически выведенного анализатором типов.
Большинство анализаторов типов поддерживают
reveal_type()в любом месте, даже если имя не импортировано изtyping. Однако импорт имени изtyping, позволяет вашему коду работать без ошибок во время выполнения и более чётко демонстрирует намерения.Добавлена в версии 3.11.
-
@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) – Принимаются произвольные другие ключевые аргументы, чтобы предоставить возможные будущие расширения.
-
eq_default (bool) – Указывает, предполагается ли, что параметр
Анализаторы типов распознают следующие необязательные параметры в спецификациях полей:
Распознанные параметры для спецификаций полей Имя параметра
Описание
initУказывает, должно ли поле включаться в синтезированный метод
__init__. Если не указано,initпо умолчаниюTrue.defaultПредоставляет значение по умолчанию для поля.
default_factoryПредоставляет обратный вызов во время выполнения, который возвращает значение по умолчанию для поля. Если ни
default, ниdefault_factoryне указаны, поле считается не имеющим значения по умолчанию и должно получить значение при создании экземпляра класса.factoryПсевдоним параметра
default_factoryдля спецификаций полей.kw_onlyУказывает, должно ли поле быть отмечено как только для ключевых аргументов. Если
True, поле будет только для ключевых аргументов. ЕслиFalse, оно не будет только для ключевых аргументов. Если не указано, используется значение параметраkw_onlyв декорированном объекте сdataclass_transform, или, если это не указано, используется значениеkw_only_defaultвdataclass_transform.aliasПредоставляет альтернативное имя для поля. Это альтернативное имя используется в синтезированном методе
__init__.Во время выполнения этот декоратор записывает свои аргументы в атрибут
__dataclass_transform__декорируемого объекта. Он не имеет других эффектов во время выполнения.См. PEP 681 для получения дополнительной информации.
Добавлена в версии 3.11.
-
@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): ... # actual implementation goes hereСм. PEP 484 для получения более подробной информации и сравнения с другими семантиками типов.
Изменено в версии 3.11: Перегруженные функции теперь можно инспектировать во время выполнения с помощью
get_overloads().
-
typing.get_overloads(func) -
Возвращает последовательность определений, помеченных
@overload, для func.func — это объект функции для реализации перегруженной функции. Например, учитывая определение
processв документации для@overload,get_overloads(process)вернёт последовательность из трёх объектов функций для трёх определённых перегрузок. Если вызвана на функции без перегрузок,get_overloads()возвращает пустую последовательность.get_overloads()может использоваться для инспектирования перегруженной функции во время выполнения.Добавлена в версии 3.11.
-
typing.clear_overloads() -
Очищает все зарегистрированные перегрузки во внутренней базе данных.
Это может быть использовано для освобождения памяти, занятой базой данных.
Добавлена в версии 3.11.
-
@typing.final -
Декоратор для указания окончательных методов и окончательных классов.
Помечание метода с помощью
@finalуказывает анализатору типов, что метод нельзя переопределять в подклассе. Помечание класса с помощью@finalуказывает, что его нельзя наследовать.Например:
class Base: @final def done(self) -> None: ... class Sub(Base): def done(self) -> None: # Error reported by type checker ... @final class Leaf: ... class Other(Leaf): # Error reported by type checker ...Проверки этих свойств во время выполнения нет. См. PEP 591 для получения более подробной информации.
Добавлена в версии 3.8.
Изменено в версии 3.11: Декоратор теперь попытается установить атрибут
__final__в значениеTrueдля помеченного объекта. Таким образом, проверка, например,if getattr(obj, "__final__", False), может использоваться во время выполнения, чтобы определить, был ли объектobjпомечен как окончательный. Если помеченный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключение.
-
@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: # Okay: overrides Base.log_status ... @override def done(self) -> None: # Error reported by type checker ...Проверки этого свойства во время выполнения нет.
Декоратор попытается установить атрибут
__override__в значениеTrueна помеченном объекте. Таким образом, проверка, например,if getattr(obj, "__override__", False), может использоваться во время выполнения, чтобы определить, был ли объектobjпомечен как переопределение. Если помеченный объект не поддерживает установку атрибутов, декоратор возвращает объект без изменений, не вызывая исключение.См. PEP 698 для получения более подробной информации.
Добавлена в версии 3.12.
-
@typing.type_check_only -
Декоратор для маркировки класса или функции как недоступных во время выполнения.
Этот декоратор сам по себе недоступен во время выполнения. Он предназначен в основном для маркировки классов, которые определены в файлах с заглушками типов, если реализация возвращает экземпляр частного класса:
@type_check_only class Response: # private or not available at runtime code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...Обратите внимание, что возвращение экземпляров частных классов не рекомендуется. Обычно предпочтительнее сделать такие классы общедоступными.
Вспомогательные средства интроспекции
-
typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False) -
Возвращает словарь, содержащий подсказки типов для функции, метода, модуля или объекта класса.
Это часто эквивалентно
obj.__annotations__, но эта функция вносит следующие изменения в словарь аннотаций:- Ссылок вперёд, закодированных как строковые литералы или объекты
ForwardRef, обрабатываются путём их вычисления в пространствах имён globalns, localns и (при необходимости) пространстве имён параметров типа объекта obj. Если globalns или localns не указаны, соответствующие пространства имён подразумеваются из obj. -
Noneзаменяется наtypes.NoneType. - Если для obj применено
@no_type_check, возвращается пустой словарь. - Если obj является классом
C, функция возвращает словарь, объединяющий аннотации из базовых классов obj с аннотациями, заданными непосредственно для obj. Это делается путём обходаC.__mro__и итеративного объединения__annotations__словарей. Аннотации классов, появляющихся раньше в порядке разрешения методов, всегда имеют приоритет перед аннотациями классов, появляющихся позже в порядке разрешения методов. - Функция рекурсивно заменяет все вхождения
Annotated[T, ...]наT, если не установлено значение include_extras, равноеTrue(см.Annotatedдля получения дополнительной информации).
См. также
inspect.get_annotations(), функцию более низкого уровня, которая возвращает аннотации более напрямую.Примечание
Если какие-либо ссылки вперёд в аннотациях 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 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является объединением или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 is a factory for creating typed dicts, # not a typed dict itself 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.
Константа
-
typing.TYPE_CHECKING -
Специальная константа, предполагаемая как
Trueсторонними статическими анализаторами типов. В процессе выполнения онаFalse.Использование:
if TYPE_CHECKING: import expensive_mod def fun(arg: 'expensive_mod.SomeType') -> None: local_var: expensive_mod.AnotherType = other_fun()Первая аннотация типа должна быть заключена в кавычки, превращая её в «ссылку вперёд», чтобы скрыть ссылку
expensive_modот интерпретатора во время выполнения. Аннотации типов для локальных переменных не вычисляются, поэтому вторая аннотация не нуждается в кавычках.Примечание
Если используется
from __future__ import annotations, аннотации не вычисляются во время определения функции. Вместо этого они хранятся как строки в__annotations__. Это делает ненужным использование кавычек вокруг аннотации (см. PEP 563).Добавлен в версии 3.5.2.
Устаревшие псевдонимы
Этот модуль определяет несколько устаревших псевдонимов для существующих классов стандартной библиотеки. Изначально они были включены в модуль typing для поддержки параметризации этих обобщённых классов с использованием []. Однако, псевдонимы стали излишними в Python 3.9, когда соответствующие существующие классы были улучшены для поддержки [] (см. PEP 585).
Избыточные типы устарели начиная с Python 3.9. Однако, хотя псевдонимы могут быть удалены в какой-то момент, их удаление в настоящее время не планируется. Поэтому интерпретатор в настоящее время не выдаёт предупреждений об устаревании для этих псевдонимов.
Если в какой-то момент будет принято решение об удалении этих устаревших псевдонимов, интерпретатор будет выдавать предупреждение об устаревании как минимум за два релиза до удаления. Псевдонимы гарантированно останутся в модуле typing без предупреждений об устаревании до Python 3.14 включительно.
Рекомендуется, чтобы средства проверки типов отмечали использование устаревших типов, если программа, которую они проверяют, ориентирована на минимальную версию Python 3.9 или более новую.
Псевдонимы встроенных типов
-
class typing.Dict(dict, MutableMapping[KT, VT]) -
Устаревший псевдоним для
dict.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
Mapping, а неdictилиtyping.Dict.Этот тип можно использовать следующим образом:
def count_words(text: str) -> Dict[str, int]: ...Устарел начиная с версии 3.9:
builtins.dictтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.List(list, MutableSequence[T]) -
Устаревший псевдоним для
list.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
SequenceилиIterable, а неlistилиtyping.List.Этот тип может быть использован следующим образом:
def vec2[T: (int, float)](x: T, y: T) -> List[T]: return [x, y] def keep_positives[T: (int, float)](vector: Sequence[T]) -> List[T]: return [item for item in vector if item > 0]Устарел начиная с версии 3.9:
builtins.listтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.Set(set, MutableSet[T]) -
Устаревший псевдоним для
builtins.set.Обратите внимание, что для аннотации аргументов предпочтительнее использовать абстрактный тип коллекции, такой как
AbstractSet, а неsetилиtyping.Set.Устарел начиная с версии 3.9:
builtins.setтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.FrozenSet(frozenset, AbstractSet[T_co]) -
Устаревший псевдоним для
builtins.frozenset.Устарел начиная с версии 3.9:
builtins.frozensetтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
typing.Tuple -
Устаревший псевдоним для
tuple.tupleиTupleимеют специальное обращение в системе типов; см. Аннотация кортежей для получения более подробной информации.Устарел начиная с версии 3.9:
builtins.tupleтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.Type(Generic[CT_co]) -
Устаревший псевдоним для
type.См. Тип объектов классов для получения подробной информации об использовании
typeилиtyping.Typeв аннотациях типов.Добавлен в версии 3.5.2.
Устарел начиная с версии 3.9:
builtins.typeтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
Псевдонимы типов в collections
-
class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT]) -
Устаревший псевдоним для
collections.defaultdict.Добавлен в версии 3.5.2.
Устарел начиная с версии 3.9:
collections.defaultdictтеперь поддерживает индексацию ([]). См. PEP 585 и Тип псевдонима обобщённого типа.
-
class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) -
Устаревший псевдоним для
collections.OrderedDict.Добавлен в версии 3.7.2.
Устарел начиная с версии 3.9:
collections.OrderedDictтеперь поддерживает индексацию ([]). См. PEP 585 и Тип псевдонима обобщённого типа.
-
class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT]) -
Устаревший псевдоним для
collections.ChainMap.Добавлен в версии 3.6.1.
Устарел начиная с версии 3.9:
collections.ChainMapтеперь поддерживает индексацию ([]). См. PEP 585 и Тип псевдонима обобщённого типа.
-
class typing.Counter(collections.Counter, Dict[T, int]) -
Устаревший псевдоним для
collections.Counter.Добавлен в версии 3.6.1.
Устарел начиная с версии 3.9:
collections.Counterтеперь поддерживает индексацию ([]). См. PEP 585 и Тип псевдонима обобщённого типа.
-
class typing.Deque(deque, MutableSequence[T]) -
Устаревший псевдоним для
collections.deque.Добавлен в версии 3.6.1.
Устарел начиная с версии 3.9:
collections.dequeтеперь поддерживает индексацию ([]). См. PEP 585 и Тип псевдонима обобщённого типа.
Псевдонимы других конкретных типов
Устарел начиная с версии 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 и Тип псевдонима обобщённого типа.
-
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
-
class typing.AbstractSet(Collection[T_co]) -
Устаревший псевдоним для
collections.abc.Set.Устарело начиная с версии 3.9:
collections.abc.Setтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
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.
Устарело начиная с версии 3.9:
collections.abc.Collectionтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.Container(Generic[T_co]) -
Устаревший псевдоним для
collections.abc.Container.Устарело начиная с версии 3.9:
collections.abc.Containerтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]]) -
Устаревший псевдоним для
collections.abc.ItemsView.Устарело начиная с версии 3.9:
collections.abc.ItemsViewтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.KeysView(MappingView, AbstractSet[KT_co]) -
Устаревший псевдоним для
collections.abc.KeysView.Устарело начиная с версии 3.9:
collections.abc.KeysViewтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.Mapping(Collection[KT], Generic[KT, VT_co]) -
Устаревший псевдоним для
collections.abc.Mapping.Этот тип может использоваться следующим образом:
def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: return word_list[word]Устарело начиная с версии 3.9:
collections.abc.Mappingтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.MappingView(Sized) -
Устаревший псевдоним для
collections.abc.MappingView.Устарело начиная с версии 3.9:
collections.abc.MappingViewтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.MutableMapping(Mapping[KT, VT]) -
Устаревший псевдоним для
collections.abc.MutableMapping.Устарело начиная с версии 3.9:
collections.abc.MutableMappingтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.MutableSequence(Sequence[T]) -
Устаревший псевдоним для
collections.abc.MutableSequence.Устарело начиная с версии 3.9:
collections.abc.MutableSequenceтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.MutableSet(AbstractSet[T]) -
Устаревший псевдоним для
collections.abc.MutableSet.Устарело начиная с версии 3.9:
collections.abc.MutableSetтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.Sequence(Reversible[T_co], Collection[T_co]) -
Устаревший псевдоним для
collections.abc.Sequence.Устарело начиная с версии 3.9:
collections.abc.Sequenceтеперь поддерживает индексацию ([]). См. PEP 585 и Тип обобщенного псевдонима.
-
class typing.ValuesView(MappingView, Collection[_VT_co]) -
Устаревшее псевдоним для
collections.abc.ValuesView.Устарело начиная с версии 3.9:
collections.abc.ValuesViewтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
Псевдонимы асинхронных ABC в collections.abc
-
class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType]) -
Устаревшее псевдоним для
collections.abc.Coroutine.Изменение вариативности и порядка типов соответствуют тем, что у
Generator, например:from collections.abc import Coroutine c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere x = c.send('hi') # Inferred type of 'x' is list[str] async def bar() -> None: y = await c # Inferred type of 'y' is intДобавлен в версии 3.5.3.
Устарело начиная с версии 3.9:
collections.abc.Coroutineтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType]) -
Устаревшее псевдоним для
collections.abc.AsyncGenerator.Асинхронный генератор можно аннотировать обобщённым типом
AsyncGenerator[YieldType, SendType]. Например:async def echo_round() -> AsyncGenerator[int, float]: sent = yield 0 while sent >= 0.0: rounded = await round(sent) sent = yield roundedВ отличие от обычных генераторов, асинхронные генераторы не могут возвращать значение, поэтому нет параметра типа
ReturnType. Как и уGenerator, параметрSendTypeведет себя контравариантно.Если ваш генератор будет только выводить значения, установите
SendTypeвNone:async def infinite_stream(start: int) -> AsyncGenerator[int, None]: while True: yield start start = await increment(start)В качестве альтернативы, аннотируйте свой генератор как имеющий возвращаемый тип
AsyncIterable[YieldType]илиAsyncIterator[YieldType]:async def infinite_stream(start: int) -> AsyncIterator[int]: while True: yield start start = await increment(start)Добавлен в версии 3.6.1.
Устарело начиная с версии 3.9:
collections.abc.AsyncGeneratorтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.AsyncIterable(Generic[T_co]) -
Устаревшее псевдоним для
collections.abc.AsyncIterable.Добавлен в версии 3.5.2.
Устарело начиная с версии 3.9:
collections.abc.AsyncIterableтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.AsyncIterator(AsyncIterable[T_co]) -
Устаревшее псевдоним для
collections.abc.AsyncIterator.Добавлен в версии 3.5.2.
Устарело начиная с версии 3.9:
collections.abc.AsyncIteratorтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
-
class typing.Awaitable(Generic[T_co]) -
Устаревшее псевдоним для
collections.abc.Awaitable.Добавлен в версии 3.5.2.
Устарело начиная с версии 3.9:
collections.abc.Awaitableтеперь поддерживает индексирование ([]). См. PEP 585 и Тип обобщённого псевдонима.
Псевдонимы других ABC в collections.abc
-
class typing.Iterable(Generic[T_co]) -
Устаревший псевдоним для
collections.abc.Iterable.Устарело начиная с версии 3.9:
collections.abc.Iterableтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
-
class typing.Iterator(Iterable[T_co]) -
Устаревший псевдоним для
collections.abc.Iterator.Устарело начиная с версии 3.9:
collections.abc.Iteratorтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
-
typing.Callable -
Устаревший псевдоним для
collections.abc.Callable.См. Аннотирование вызываемых объектов для получения подробной информации о том, как использовать
collections.abc.Callableиtyping.Callableв аннотациях типов.Устарело начиная с версии 3.9:
collections.abc.Callableтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.Изменено в версии 3.10:
Callableтеперь поддерживаетParamSpecиConcatenate. См. PEP 612 для получения дополнительной информации.
-
class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType]) -
Устаревший псевдоним для
collections.abc.Generator.Генератор можно аннотировать с помощью дженерического типа
Generator[YieldType, SendType, ReturnType]. Например:def echo_round() -> Generator[int, float, str]: sent = yield 0 while sent >= 0: sent = yield round(sent) return 'Done'Обратите внимание, что в отличие от многих других дженериков в модуле typing, поведение
SendTypeуGeneratorконтравариантно, а не ковариантно или инвариантно.Если ваш генератор будет только выдавать значения, установите
SendTypeиReturnTypeвNone:def infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1В качестве альтернативы, аннотируйте свой генератор, указав возвращаемый тип либо
Iterable[YieldType]илиIterator[YieldType]:def infinite_stream(start: int) -> Iterator[int]: while True: yield start start += 1Устарело начиная с версии 3.9:
collections.abc.Generatorтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
-
class typing.Hashable -
Устаревший псевдоним для
collections.abc.Hashable.Устарело начиная с версии 3.12: Используйте
collections.abc.Hashableнапрямую вместо этого.
-
class typing.Reversible(Iterable[T_co]) -
Устаревший псевдоним для
collections.abc.Reversible.Устарело начиная с версии 3.9:
collections.abc.Reversibleтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
-
class typing.Sized -
Устаревший псевдоним для
collections.abc.Sized.Устарело начиная с версии 3.12: Используйте
collections.abc.Sizedнапрямую вместо этого.
Псевдонимы ABC contextlib
-
class typing.ContextManager(Generic[T_co]) -
Устаревший псевдоним для
contextlib.AbstractContextManager.Добавлен в версии 3.5.4.
Устарело начиная с версии 3.9:
contextlib.AbstractContextManagerтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
-
class typing.AsyncContextManager(Generic[T_co]) -
Устаревший псевдоним для
contextlib.AbstractAsyncContextManager.Добавлен в версии 3.6.2.
Устарело начиная с версии 3.9:
contextlib.AbstractAsyncContextManagerтеперь поддерживает индексирование ([]). См. PEP 585 и Тип псевдонима дженерика.
График устаревания основных функций
Определенные функции в typing устарели и могут быть удалены в будущей версии Python. В следующей таблице обобщены основные устаревания для вашего удобства. Данные могут быть изменены, и не все устаревания перечислены.
Функция | Устарела в | Прогнозируемое удаление | PEP/запрос |
|---|---|---|---|
| 3.8 | 3.13 | |
| 3.9 | Не определено (см. Устаревшие псевдонимы для получения дополнительной информации) | |
3.9 | 3.14 | ||
3.11 | Не определено | ||
3.12 | Не определено | ||
3.12 | Не определено |
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/typing.html