Spec-Zone.ru › Python 3.9

typing — Поддержка типов

Новое в версии 3.5.

Исходный код: Lib/typing.py

Примечание

Интерпретатор Python не проверяет типы функций и переменных. Они могут использоваться сторонними инструментами, такими как проверяющие типы, IDE, средства проверки кода и т. д.

Этот модуль предоставляет поддержку типов во время выполнения. Наиболее фундаментальная поддержка состоит из типов Any, Union, Callable, TypeVar и Generic. Полную спецификацию можно найти в PEP 484. Упрощённое введение в типы можно найти в PEP 483.

Нижеприведенная функция принимает и возвращает строку и аннотирована следующим образом:

def greeting(name: str) -> str:
    return 'Hello ' + name

В функции greeting, аргумент name ожидается типа str, а тип возвращаемого значения str. В качестве аргументов принимаются и подтипы.

В модуль typing часто добавляются новые функции. Пакет typing_extensions предоставляет обратные порты этих новых функций для старых версий Python.

Соответствующие PEP

После первоначального введения типов в PEP 484 и PEP 483, ряд PEP модифицировали и улучшили фреймворк Python для аннотаций типов. К ним относятся:

  • PEP 526: Синтаксис аннотаций переменных

    Вводит синтаксис для аннотирования переменных вне определений функций и ClassVar

  • PEP 544: Протоколы: структурное подтипирование (статическое утиное наследование)

    Вводит Protocol и декоратор @runtime_checkable

  • PEP 585: Типизация дженериков в стандартных коллекциях

    Вводит types.GenericAlias и возможность использовать классы стандартной библиотеки как типы дженериков

  • PEP 586: Буквальные типы

    Вводит Literal

  • PEP 589: TypedDict: аннотации типов для словарей с фиксированным набором ключей

    Вводит TypedDict

  • PEP 591: Добавление квалификатора final к typing

    Вводит Final и декоратор @final

  • PEP 593: Гибкие аннотации функций и переменных

    Вводит Annotated

Псевдонимы типов

Псевдоним типа определяется присваиванием типа псевдониму. В этом примере Vector и list[float] будут считаться взаимозаменяемыми синонимами:

Vector = list[float]

def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]

# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])

Псевдонимы типов полезны для упрощения сложных сигнатур типов. Например:

from collections.abc import Sequence

ConnectionOptions = dict[str, str]
Address = tuple[str, int]
Server = tuple[Address, ConnectionOptions]

def broadcast_message(message: str, servers: Sequence[Server]) -> None:
    ...

# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
        message: str,
        servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None:
    ...

Обратите внимание, что None в качестве аннотации типа — это особый случай и заменяется на type(None).

NewType

Используйте помощник NewType() для создания отличных типов:

from typing import NewType

UserId = NewType('UserId', int)
some_id = UserId(524313)

Статический проверяющий типы будет обрабатывать новый тип так, как будто это подкласс исходного типа. Это полезно для обнаружения логических ошибок:

def get_user_name(user_id: UserId) -> str:
    ...

# typechecks
user_a = get_user_name(UserId(42351))

# does not typecheck; an int is not a UserId
user_b = get_user_name(-1)

Вы по-прежнему можете выполнять все int операции над переменной типа UserId, но результат всегда будет типа int. Это позволяет передавать UserId туда, где ожидается int, но предотвращает случайное создание UserId неверным способом:

# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)

Обратите внимание, что эти проверки применяются только статическим проверяющим типов. Во время выполнения оператор Derived = NewType('Derived', Base) превратит Derived в вызываемый объект, который немедленно возвращает переданный ему параметр. Это означает, что выражение Derived(some_value) не создаёт новый класс и не вносит дополнительную нагрузку по сравнению с обычным вызовом функции.

Более точно, выражение some_value is Derived(some_value) всегда истинно во время выполнения.

Это также означает, что создать подтип Derived невозможно, поскольку он представляет собой функцию тождества во время выполнения, а не фактический тип:

from typing import NewType

UserId = NewType('UserId', int)

# Fails at runtime and does not typecheck
class AdminUserId(UserId): pass

Однако можно создать NewType() на основе «производного» NewType:

from typing import NewType

UserId = NewType('UserId', int)

ProUserId = NewType('ProUserId', UserId)

и проверка типов для ProUserId будет работать как ожидается.

См. PEP 484 для получения более подробной информации.

Примечание

Помните, что использование псевдонима типа объявляет два типа эквивалентными друг другу. Выполнение Alias = Original заставит статический проверяющий типы рассматривать Alias как точно эквивалентный Original во всех случаях. Это полезно, когда необходимо упростить сложные сигнатуры типов.

В отличие от этого, NewType объявляет один тип подтипом другого. Выполнение Derived = NewType('Derived', Original) заставит статический проверяющий типы рассматривать Derived как подкласс Original, что означает, что значение типа Original нельзя использовать там, где ожидается значение типа Derived. Это полезно для предотвращения логических ошибок с минимальными затратами во время выполнения.

Новое в версии 3.5.2.

Callable

Фреймворки, ожидающие функции обратного вызова с определёнными сигнатурами, могут быть аннотированы с помощью Callable[[Arg1Type, Arg2Type], ReturnType].

Например:

from collections.abc import Callable

def feeder(get_next_item: Callable[[], str]) -> None:
    # Body

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    # Body

async def on_update(value: str) -> None:
    # Body
callback: Callable[[str], Awaitable[None]] = on_update

Можно объявить тип возвращаемого значения вызываемого объекта без указания сигнатуры вызова, заменив список аргументов в аннотации типа на эллипсис: Callable[..., ReturnType].

Дженерики

Поскольку информацию о типе объектов, хранящихся в контейнерах, нельзя статически вывести обобщённым способом, абстрактные базовые классы были расширены, чтобы поддерживать подписку для обозначения ожидаемых типов для элементов контейнера.

from collections.abc import Mapping, Sequence

def notify_by_email(employees: Sequence[Employee],
                    overrides: Mapping[str, str]) -> None: ...

Дженерики могут быть параметризованы с помощью фабрики, доступной в typing, под названием TypeVar.

from collections.abc import Sequence
from typing import TypeVar

T = TypeVar('T')      # Declare type variable

def first(l: Sequence[T]) -> T:   # Generic function
    return l[0]

Пользовательские обобщенные типы

Пользовательский класс может быть определен как обобщенный класс.

from typing import TypeVar, Generic
from logging import Logger

T = TypeVar('T')

class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value

    def set(self, new: T) -> None:
        self.log('Set ' + repr(self.value))
        self.value = new

    def get(self) -> T:
        self.log('Get ' + repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info('%s: %s', self.name, message)

Generic[T] в качестве базового класса определяет, что класс LoggedVar принимает один параметр типа T . Это также делает T допустимым типом внутри тела класса.

Базовый класс Generic определяет __class_getitem__(), чтобы LoggedVar[t] было допустимым типом:

from collections.abc import Iterable

def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
    for var in vars:
        var.set(0)

Обобщенный тип может иметь любое количество переменных типа. Все варианты TypeVar допустимы в качестве параметров для обобщенного типа:

from typing import TypeVar, Generic, Sequence

T = TypeVar('T', contravariant=True)
B = TypeVar('B', bound=Sequence[bytes], covariant=True)
S = TypeVar('S', int, str)

class WeirdTrio(Generic[T, B, S]):
    ...

Каждый аргумент переменной типа для Generic должен быть различным. Следовательно, это недопустимо:

from typing import TypeVar, Generic
...

T = TypeVar('T')

class Pair(Generic[T, T]):   # INVALID
    ...

Вы можете использовать множественное наследование с Generic:

from collections.abc import Sized
from typing import TypeVar, Generic

T = TypeVar('T')

class LinkedList(Sized, Generic[T]):
    ...

При наследовании от обобщенных классов некоторые переменные типа могут быть фиксированными:

from collections.abc import Mapping
from typing import TypeVar

T = TypeVar('T')

class MyDict(Mapping[str, T]):
    ...

В этом случае MyDict имеет один параметр, T.

Использование обобщенного класса без указания параметров типа предполагает Any для каждой позиции. В следующем примере, MyIterable не является обобщенным, но неявно наследуется от Iterable[Any]:

from collections.abc import Iterable

class MyIterable(Iterable): # Same as Iterable[Any]

Также поддерживаются псевдонимы пользовательских обобщенных типов. Примеры:

from collections.abc import Iterable
from typing import TypeVar, Union
S = TypeVar('S')
Response = Union[Iterable[S], int]

# Return type here is same as Union[Iterable[str], int]
def response(query: str) -> Response[str]:
    ...

T = TypeVar('T', int, float, complex)
Vec = Iterable[tuple[T, T]]

def inproduct(v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]]
    return sum(x*y for x, y in v)

Изменено в версии 3.7: Generic больше не имеет пользовательского метакласса.

Пользовательский обобщенный класс может иметь 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:
    # Typechecks; 'item' could be any type,
    # and that type might have a 'bar' method
    item.bar()
    ...

Обратите внимание, что проверка типов не выполняется при присваивании значения типа Any более точному типу. Например, статический проверяющий типов не выдал ошибку при присваивании a к s, даже если s был объявлен как типа str и получает значение int во время выполнения!

Кроме того, все функции без типа возвращаемого значения или типов параметров неявно используют Any:

def legacy_parser(text):
    ...
    return data

# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
    ...
    return data

Это поведение позволяет использовать Any как путь выхода, когда вам нужно смешивать динамический и статически типизированный код.

Сравните поведение Any с поведением object. Подобно Any, каждый тип является подтипом object. Однако, в отличие от Any, обратное неверно: object не является подтипом каждого другого типа.

Это означает, что когда тип значения равен object, проверяющий типов отклонит почти все операции над ним, и присвоение его переменной (или использование в качестве значения возврата) более специализированного типа является ошибкой типа. Например:

def hash_a(item: object) -> int:
    # Fails; an object does not have a 'magic' method.
    item.magic()
    ...

def hash_b(item: Any) -> int:
    # Typechecks
    item.magic()
    ...

# Typechecks, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")

# Typechecks, since Any is compatible with all types
hash_b(42)
hash_b("foo")

Используйте object, чтобы указать, что значение может быть любого типа безопасным способом. Используйте Any, чтобы указать, что значение имеет динамическую типизацию.

Номинальный против структурного подтипирования

Изначально PEP 484 определил систему статической типизации Python как использующую номинальное подтипирование. Это означает, что класс A разрешается там, где ожидается класс B тогда и только тогда, когда A является подклассом B.

Это требование ранее также применялось к абстрактным базовым классам, таким как Iterable. Проблема этого подхода заключалась в том, что класс должен был быть явно помечен для поддержки их, что непитонично и отличается от того, что обычно делается в идиоматичном динамически типизированном коде Python. Например, это соответствует PEP 484:

from collections.abc import Sized, Iterable, Iterator

class Bucket(Sized, Iterable[int]):
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

PEP 544 позволяет решить эту проблему, позволяя пользователям писать вышеприведенный код без явных базовых классов в определении класса, позволяя Bucket неявно рассматриваться как подтип как Sized и Iterable[int] проверяющими типами. Это известно как структурное подтипирование (или статическая утиная типизация):

from collections.abc import Iterator, Iterable

class Bucket:  # Note: no base classes
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket())  # Passes type check

Кроме того, наследуя от специального класса Protocol, пользователь может определять новые пользовательские протоколы для полного использования структурного подтипирования (см. примеры ниже).

Содержание модуля

Модуль определяет следующие классы, функции и декораторы.

Примечание

Этот модуль определяет несколько типов, которые являются подклассами предварительно существующих стандартных классов библиотеки, которые также расширяют Generic для поддержки переменных типа внутри []. Эти типы стали избыточными в Python 3.9, когда соответствующие предварительно существующие классы были расширены для поддержки [].

Избыточные типы устарели начиная с Python 3.9, но интерпретатор не будет выдавать предупреждений об устаревании. Ожидается, что проверяющие типов будут отмечать устаревшие типы, когда проверяемая программа направлена на Python 3.9 или более поздние версии.

Устаревшие типы будут удалены из модуля typing в первой версии Python, выпущенной через 5 лет после выпуска Python 3.9.0. См. подробности в PEP 585 — Обобщенные подсказки типов в стандартных коллекциях.

Специальные примитивы типов

Специальные типы

Их можно использовать в качестве типов в аннотациях и они не поддерживают [].

typing.Any

Специальный тип, указывающий на не ограниченный тип.

  • Каждый тип совместим с Any.
  • Any совместим с каждым типом.
typing.NoReturn

Специальный тип, указывающий, что функция никогда не возвращает значение. Например:

from typing import NoReturn

def stop() -> NoReturn:
    raise RuntimeError('no way')

Новое в версии 3.5.4.

Новое в версии 3.6.2.

Специальные формы

Их можно использовать в качестве типов в аннотациях, используя [], каждая из которых имеет уникальный синтаксис.

typing.Tuple

Кортежный тип; Tuple[X, Y] — это тип кортежа из двух элементов, первый элемент типа X, а второй — типа Y. Тип пустого кортежа можно записать как Tuple[()].

Пример: Tuple[T1, T2] — это кортеж из двух элементов, соответствующих типам переменных T1 и T2. Tuple[int, float, str] — это кортеж из int, float и string.

Для указания кортежа переменной длины однородного типа используйте литерал многоточие, например Tuple[int, ...]. Обычный Tuple эквивалентен Tuple[Any, ...], а также tuple.

Устарело начиная с версии 3.9: builtins.tuple теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

typing.Union

Тип объединения; Union[X, Y] означает либо X, либо Y.

Для определения объединения используйте, например, Union[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]
    
  • При сравнении объединений порядок аргументов игнорируется, например:

    Union[int, str] == Union[str, int]
    
  • Нельзя наследовать или создавать экземпляр объединения.
  • Нельзя записать Union[X][Y].
  • Можно использовать Optional[X] в качестве сокращения для Union[X, None].

Изменено в версии 3.7: Не удаляйте явные подклассы из объединений во время выполнения.

typing.Optional

Необязательный тип.

Optional[X] эквивалентно Union[X, None].

Обратите внимание, что это не то же самое, что необязательный аргумент, который имеет значение по умолчанию. Необязательный аргумент с значением по умолчанию не требует квалификатора Optional в аннотации типа, просто потому, что он необязательный. Например:

def foo(arg: int = 0) -> None:
    ...

С другой стороны, если разрешено явное значение None , использование Optional уместно, независимо от того, является ли аргумент необязательным или нет. Например:

def foo(arg: Optional[int] = None) -> None:
    ...
typing.Callable

Тип вызываемой функции; Callable[[int], str] — функция типа (int) -> str.

Синтаксис подписки должен всегда использоваться ровно с двумя значениями: списком аргументов и типом возвращаемого значения. Список аргументов должен быть списком типов или многоточием; тип возвращаемого значения должен быть единственным типом.

Нет синтаксиса для указания необязательных или ключевых аргументов; такие типы функций редко используются в качестве типов обратных вызовов. Callable[..., ReturnType] (литерал многоточия) может использоваться для примечания вызываемой функции, принимающей любое количество аргументов и возвращающей ReturnType. Обычный Callable эквивалентен Callable[..., Any], и, в свою очередь, collections.abc.Callable.

Устарело начиная с версии 3.9: collections.abc.Callable теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.Type(Generic[CT_co])

Переменная, аннотированная C , может принимать значение типа C . В отличие от этого, переменная, аннотированная Type[C] , может принимать значения, которые являются сами классами — конкретно, она будет принимать *объект класса* C. Например:

a = 3         # Has type 'int'
b = int       # Has type 'Type[int]'
c = type(a)   # Also has type 'Type[int]'

Обратите внимание, что Type[C] является ковариативным:

class User: ...
class BasicUser(User): ...
class ProUser(User): ...
class TeamUser(User): ...

# Accepts User, BasicUser, ProUser, TeamUser, ...
def make_new_user(user_class: Type[User]) -> User:
    # ...
    return user_class()

Тот факт, что Type[C] является ковариативным, подразумевает, что все подклассы C должны реализовывать ту же сигнатуру конструктора и сигнатуры методов класса, что и C . Проверяющий типов должен отмечать нарушения этого, но также должен разрешать вызовы конструкторов в подклассах, которые соответствуют вызовам конструкторов в указанном базовом классе. Способ, которым проверяющий типов должен обрабатывать этот конкретный случай, может измениться в будущих пересмотрах PEP 484.

Единственными допустимыми параметрами для Type являются классы, Any, переменные типов и объединения любых из этих типов. Например:

def new_non_team_user(user_class: Type[Union[BasicUser, ProUser]]): ...

Type[Any] эквивалентно Type, которое в свою очередь эквивалентно type, являющемуся корнем иерархии метаклассов Python.

Новое в версии 3.5.2.

Устарело начиная с версии 3.9: builtins.type теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

typing.Literal

Тип, который может использоваться для указания проверяющим типов, что соответствующая переменная или параметр функции имеет значение, эквивалентное указанному литералу (или одному из нескольких литералов). Например:

def validate_simple(data: Any) -> Literal[True]:  # always returns True
    ...

MODE = Literal['r', 'rb', 'w', 'wb']
def open_helper(file: str, mode: MODE) -> str:
    ...

open_helper('/some/path', 'r')  # Passes type check
open_helper('/other/path', 'typo')  # Error in type checker

Literal[...] не может быть наследуемым. Во время выполнения произвольное значение разрешено в качестве аргумента типа Literal[...], но проверяющие типы могут наложить ограничения. См. PEP 586 для получения дополнительной информации о типах литералов.

Новое в версии 3.8.

Изменено в версии 3.9.1: Literal теперь удаляет дублирующие параметры. Сравнения на равенство объектов Literal больше не зависят от порядка. Объекты Literal теперь будут поднимать исключение TypeError при сравнении на равенство, если один из их параметров не является хешируемым.

typing.ClassVar

Специальная конструкция типа для маркировки переменных класса.

Как введено в PEP 526, аннотация переменной, обернутой в ClassVar, указывает, что данный атрибут предназначен для использования в качестве переменной класса и не должен устанавливаться для экземпляров этого класса. Использование:

class Starship:
    stats: ClassVar[dict[str, int]] = {} # class variable
    damage: int = 10                     # instance variable

ClassVar принимает только типы и не может быть дальше подписан.

ClassVar не является классом сам по себе и не должен использоваться с isinstance() или issubclass(). ClassVar не изменяет поведение Python во время выполнения, но может использоваться сторонними проверяющими типами. Например, проверяющий типы может отметить следующий код как ошибку:

enterprise_d = Starship(3000)
enterprise_d.stats = {} # Error, setting class variable on instance
Starship.stats = {}     # This is OK

Новое в версии 3.5.3.

typing.Final

Специальная конструкция типа для указания проверяющим типам, что имя не может быть повторно назначено или переопределено в подклассе. Например:

MAX_SIZE: Final = 9000
MAX_SIZE += 1  # Error reported by type checker

class Connection:
    TIMEOUT: Final[int] = 10

class FastConnector(Connection):
    TIMEOUT = 1  # Error reported by type checker

Нет проверки этих свойств во время выполнения. См. PEP 591 для получения дополнительной информации.

Новое в версии 3.8.

END_OF_DOCUMENT_MARKER
typing.Annotated

Тип, введённый в PEP 593 (Flexible function and variable annotations), для добавления меток, специфичных для контекста, к существующим типам (возможно, несколько таких меток, так как Annotated является вариативным). В частности, к типу T можно добавить метаданные x с помощью подсказки типа Annotated[T, x]. Эти метаданные могут использоваться для статического анализа или во время выполнения. Если библиотека (или инструмент) встречает подсказку типа Annotated[T, x] и не имеет специальной логики для метаданных x, она должна проигнорировать её и просто рассматривать тип как T. В отличие от no_type_check функциональности, которая сейчас существует в модуле typing, которая полностью отключает проверку типов для аннотаций функций или классов, тип Annotated позволяет выполнять статическую проверку типов T (которая может безопасно игнорировать x) вместе с доступом ко времени выполнения к x в рамках конкретного приложения.

В конечном счете, ответственность за то, как интерпретировать аннотации (если вообще), лежит на инструменте или библиотеке, встречающей тип Annotated. Инструмент или библиотека, встретив тип Annotated, могут просмотреть аннотации, чтобы определить, представляют ли они интерес (например, используя isinstance()).

Если инструмент или библиотека не поддерживают аннотации или встречают неизвестную аннотацию, она должна просто проигнорировать её и рассматривать аннотированный тип как базовый тип.

Потребителю аннотаций необходимо самостоятельно определить, разрешено ли клиенту иметь несколько аннотаций к одному типу и как объединить эти аннотации.

Поскольку тип Annotated позволяет помещать несколько аннотаций одного (или разных) типа(ов) на любой узел, инструменты или библиотеки, использующие эти аннотации, отвечают за обработку потенциальных дубликатов. Например, если вы выполняете анализ диапазона значений, вы можете разрешить это:

T1 = Annotated[int, ValueRange(-10, 5)]
T2 = Annotated[T1, ValueRange(-20, 3)]

Передача include_extras=True в get_type_hints() позволяет получить дополнительные аннотации во время выполнения.

Подробности синтаксиса:

  • Первый аргумент Annotated должен быть допустимым типом
  • Поддерживаются несколько аннотаций типа (Annotated поддерживает вариативные аргументы):

    Annotated[int, ValueRange(3, 10), ctype("char")]
    
  • Annotated должен быть вызван как минимум с двумя аргументами (Annotated[int] недопустимо)
  • Порядок аннотаций сохраняется и имеет значение для проверок на равенство:

    Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[
        int, ctype("char"), ValueRange(3, 10)
    ]
    
  • Вложенные типы Annotated раскладываются, причём метаданные упорядочены, начиная с самой внутренней аннотации:

    Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[
        int, ValueRange(3, 10), ctype("char")
    ]
    
  • Дублированные аннотации не удаляются:

    Annotated[int, ValueRange(3, 10)] != Annotated[
        int, ValueRange(3, 10), ValueRange(3, 10)
    ]
    
  • Annotated может использоваться с вложенными и обобщёнными псевдонимами:

    T = TypeVar('T')
    Vec = Annotated[list[tuple[T, T]], MaxLen(10)]
    V = Vec[int]
    
    V == Annotated[list[tuple[int, int]], MaxLen(10)]
    

Введено в версии 3.9.

Создание обобщённых типов

Они не используются в аннотациях. Это строительные блоки для создания обобщённых типов.

class typing.Generic

Абстрактный базовый класс для обобщённых типов.

Обобщённый тип обычно объявляется путём наследования от экземпляра этого класса с одной или несколькими переменными типа. Например, обобщённый тип отображения может быть определён как:

class Mapping(Generic[KT, VT]):
    def __getitem__(self, key: KT) -> VT:
        ...
        # Etc.

Этот класс затем можно использовать следующим образом:

X = TypeVar('X')
Y = TypeVar('Y')

def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y:
    try:
        return mapping[key]
    except KeyError:
        return default
class typing.TypeVar

Переменная типа.

Использование:

T = TypeVar('T')  # Can be anything
S = TypeVar('S', bound=str)  # Can be any subtype of str
A = TypeVar('A', str, bytes)  # Must be exactly str or bytes

Переменные типа в основном нужны для статических проверок типов. Они служат параметрами для обобщённых типов и обобщённых определений функций. См. Generic для получения дополнительной информации об обобщённых типах. Обобщённые функции работают следующим образом:

def repeat(x: T, n: int) -> Sequence[T]:
    """Return a list containing n references to x."""
    return [x]*n


def print_capitalized(x: S) -> S:
    """Print x capitalized, and return x."""
    print(x.capitalize())
    return x


def concatenate(x: A, y: A) -> A:
    """Add two strings or bytes objects together."""
    return x + y

Обратите внимание, что переменные типа могут быть связаны, ограничены или ни тем, ни другим, но не могут быть одновременно связаны и ограничены.

Связанные и ограниченные переменные типа имеют разные семантики в нескольких важных аспектах. Использование ограниченной переменной типа означает, что TypeVar может быть решена только как один из указанных ограничений:

a = concatenate('one', 'two')  # Ok, variable 'a' has type 'str'
b = concatenate(StringSubclass('one'), StringSubclass('two'))  # Inferred type of variable 'b' is 'str',
                                                               # despite 'StringSubclass' being passed in
c = concatenate('one', b'two')  # error: type variable 'A' can be either 'str' or 'bytes' in a function call, but not both

Однако использование связанной переменной типа означает, что TypeVar будет решена с использованием наиболее конкретного возможного типа:

print_capitalized('a string')  # Ok, output has type 'str'

class StringSubclass(str):
    pass

print_capitalized(StringSubclass('another string'))  # Ok, output has type 'StringSubclass'
print_capitalized(45)  # error: int is not a subtype of str

Переменные типа могут быть связаны с конкретными типами, абстрактными типами (ABC или протоколами), а также объединениями типов:

U = TypeVar('U', bound=str|bytes)  # Can be any subtype of the union str|bytes
V = TypeVar('V', bound=SupportsAbs)  # Can be anything with an __abs__ method

Связанные переменные типа особенно полезны для аннотирования classmethods, которые служат альтернативными конструкторами. В следующем примере (© Raymond Hettinger) переменная типа C связана с классом Circle через использование обратной ссылки. Использование этой переменной типа для аннотирования метода with_circumference вместо жёсткого кодирования возвращаемого типа как Circle означает, что система проверки типов может правильно определить возвращаемый тип, даже если метод вызывается на подклассе:

import math

C = TypeVar('C', bound='Circle')

class Circle:
    """An abstract circle"""

    def __init__(self, radius: float) -> None:
        self.radius = radius

    # Use a type variable to show that the return type
    # will always be an instance of whatever ``cls`` is
    @classmethod
    def with_circumference(cls: type[C], circumference: float) -> C:
        """Create a circle with the specified circumference"""
        radius = circumference / (math.pi * 2)
        return cls(radius)


class Tire(Circle):
    """A specialised circle (made out of rubber)"""

    MATERIAL = 'rubber'


c = Circle.with_circumference(3)  # Ok, variable 'c' has type 'Circle'
t = Tire.with_circumference(4)  # Ok, variable 't' has type 'Tire' (not 'Circle')

Во время выполнения isinstance(x, T) поднимет TypeError. В целом, isinstance() и issubclass() не должны использоваться с типами.

Переменные типа могут быть помечены как ковариантные или контравариантные, передавая covariant=True или contravariant=True. См. PEP 484 для получения дополнительной информации. По умолчанию переменные типа являются инвариантными.

typing.AnyStr

AnyStr — это constrained type variable, определённый как AnyStr = TypeVar('AnyStr', str, bytes).

Он предназначен для функций, которые могут принимать любой тип строки, не позволяя смешивать различные типы строк. Например:

def concat(a: AnyStr, b: AnyStr) -> AnyStr:
    return a + b

concat(u"foo", u"bar")  # Ok, output has type 'unicode'
concat(b"foo", b"bar")  # Ok, output has type 'bytes'
concat(u"foo", b"bar")  # Error, cannot mix unicode and bytes
class typing.Protocol(Generic)

Базовый класс для классов протоколов. Классы протоколов определяются так:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Такие классы в основном используются со статическими системами проверки типов, которые распознают структурное подтипирование (статическое переопределение типов), например:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

См. PEP 544 для получения подробностей. Классы протоколов, помеченные runtime_checkable() (описанные позже), действуют как простые протоколы времени выполнения, которые проверяют только наличие заданных атрибутов, игнорируя их сигнатуры типов.

Классы протоколов могут быть обобщёнными, например:

class GenProto(Protocol[T]):
    def meth(self) -> T:
        ...

Введено в версии 3.8.

@typing.runtime_checkable

Помечает класс протокола как протокол времени выполнения.

Такой протокол может использоваться с isinstance() и issubclass(). Это вызывает TypeError, если применяется к неклассу протокола. Это позволяет выполнить простую структурную проверку, очень похожую на «одноходовки» в collections.abc, такие как Iterable. Например:

@runtime_checkable
class Closable(Protocol):
    def close(self): ...

assert isinstance(open('/some/file'), Closable)

Примечание

runtime_checkable() будет проверять только наличие необходимых методов, а не их сигнатуры типов! Например, builtins.complex реализует __float__(), поэтому он проходит проверку issubclass() по отношению к SupportsFloat. Однако метод complex.__float__ существует только для вызова TypeError с более информативным сообщением.

Введено в версии 3.8.

Другие специальные директивы

Эти директивы не используются в аннотациях. Они являются строительными блоками для объявления типов.

class typing.NamedTuple

Набранная версия collections.namedtuple().

Использование:

class Employee(NamedTuple):
    name: str
    id: int

Это эквивалентно:

Employee = collections.namedtuple('Employee', ['name', 'id'])

Для присвоения значений по умолчанию полям, можно присвоить им значение в теле класса:

class Employee(NamedTuple):
    name: str
    id: int = 3

employee = Employee('Guido')
assert employee.id == 3

Поля с значениями по умолчанию должны следовать за полями без значений по умолчанию.

Полученный класс имеет дополнительный атрибут __annotations__ , содержащий словарь, который сопоставляет имена полей с типами полей. (Имена полей находятся в атрибуте _fields, а значения по умолчанию — в атрибуте _field_defaults, оба из которых являются частью API namedtuple().)

NamedTuple подклассы также могут иметь строки документации и методы:

class Employee(NamedTuple):
    """Represents an employee."""
    name: str
    id: int = 3

    def __repr__(self) -> str:
        return f'<Employee {self.name}, id={self.id}>'

Обратная совместимость:

Employee = NamedTuple('Employee', [('name', str), ('id', int)])

Изменено в версии 3.6: Добавлена поддержка синтаксиса аннотации переменных PEP 526.

Изменено в версии 3.6.1: Добавлена поддержка значений по умолчанию, методов и строк документации.

Изменено в версии 3.8: Атрибуты _field_types и __annotations__ теперь являются обычными словарями вместо экземпляров OrderedDict.

Изменено в версии 3.9: Убран атрибут _field_types в пользу более стандартного атрибута __annotations__ , содержащего ту же информацию.

typing.NewType(name, tp)

Вспомогательная функция для указания отличного типа для проверки типов, см. NewType. Во время выполнения она возвращает функцию, которая возвращает свой аргумент. Использование:

UserId = NewType('UserId', int)
first_user = UserId(1)

Добавлена в версии 3.5.2.

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)
    

Функциональный синтаксис также должен использоваться, когда любой из ключей не является допустимым идентификатором идентификатором, например, потому что это ключевые слова или содержат дефисы. Пример:

# 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. Можно переопределить это, указав полное соответствие. Использование:

class Point2D(TypedDict, total=False):
    x: int
    y: int

# Alternative syntax
Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)

Это означает, что у Point2D TypedDict могут отсутствовать любые ключи. Проверяющая система типов ожидает только литерал False или True в качестве значения аргумента total. True — значение по умолчанию, которое делает все элементы, определенные в теле класса, обязательными.

Класс TypedDict типа может наследоваться от одного или нескольких других TypedDict типов, используя синтаксис на основе класса. Использование:

class Point3D(Point2D):
    z: int

Point3D имеет три элемента: x, y и z. Он эквивалентен этому определению:

class Point3D(TypedDict):
    x: int
    y: int
    z: int

TypedDict не может наследоваться от класса, который не является TypedDict, в частности, включая Generic. Например:

class X(TypedDict):
    x: int

class Y(TypedDict):
    y: int

class Z(object): pass  # A non-TypedDict class

class XY(X, Y): pass  # OK

class XZ(X, Z): pass  # raises TypeError

T = TypeVar('T')
class XT(X, Generic[T]): pass  # raises TypeError

TypedDict может быть проинспектирован через __annotations__, __total__, __required_keys__ и __optional_keys__.

__total__

Point2D.__total__ возвращает значение аргумента total. Пример:

>>> from typing import TypedDict
>>> class Point2D(TypedDict): pass
>>> Point2D.__total__
True
>>> class Point2D(TypedDict, total=False): pass
>>> Point2D.__total__
False
>>> class Point3D(Point2D): pass
>>> Point3D.__total__
True
__required_keys__
__optional_keys__

Point2D.__required_keys__ и Point2D.__optional_keys__ возвращают объекты frozenset, содержащие необходимые и необязательные ключи соответственно. В настоящее время единственный способ объявить как необходимые, так и необязательные ключи в одном TypedDict — смешанное наследование, объявление TypedDict с одним значением для аргумента total и затем наследование от другого TypedDict с другим значением для total. Использование:

>>> class Point2D(TypedDict, total=False):
...     x: int
...     y: int
...
>>> class Point3D(Point2D):
...     z: int
...
>>> Point3D.__required_keys__ == frozenset({'z'})
True
>>> Point3D.__optional_keys__ == frozenset({'x', 'y'})
True

См. PEP 589 для получения дополнительных примеров и подробных правил использования TypedDict.

Добавлена в версии 3.8.

Обобщённые конкретные коллекции

Соответствующие встроенным типам

class typing.Dict(dict, MutableMapping[KT, VT])

Обобщённая версия dict. Полезна для аннотирования типов возвращаемых значений. Для аннотирования аргументов предпочтительнее использовать абстрактные типы коллекций, такие как Mapping.

Этот тип может использоваться следующим образом:

def count_words(text: str) -> Dict[str, int]:
    ...

Устарело начиная с версии 3.9: builtins.dict теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.List(list, MutableSequence[T])

Обобщённая версия list. Полезна для аннотирования типов возвращаемых значений. Для аннотирования аргументов предпочтительнее использовать абстрактные типы коллекций, такие как Sequence или Iterable.

Этот тип может использоваться следующим образом:

T = TypeVar('T', int, float)

def vec2(x: T, y: T) -> List[T]:
    return [x, y]

def keep_positives(vector: Sequence[T]) -> List[T]:
    return [item for item in vector if item > 0]

Устарело начиная с версии 3.9: builtins.list теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.Set(set, MutableSet[T])

Обобщённая версия builtins.set. Полезна для аннотирования типов возвращаемых значений. Для аннотирования аргументов предпочтительнее использовать абстрактные типы коллекций, такие как AbstractSet.

Устарело начиная с версии 3.9: builtins.set теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.FrozenSet(frozenset, AbstractSet[T_co])

Обобщённая версия builtins.frozenset.

Устарело начиная с версии 3.9: builtins.frozenset теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

Примечание

Tuple — это специальный вид.

Соответствующие типам в collections

class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])

Обобщённая версия collections.defaultdict.

Добавлена в версии 3.5.2.

Устарело начиная с версии 3.9: collections.defaultdict теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])

Обобщённая версия collections.OrderedDict.

Добавлена в версии 3.7.2.

Устарело начиная с версии 3.9: collections.OrderedDict теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])

Обобщённая версия collections.ChainMap.

Добавлена в версии 3.5.4.

Добавлена в версии 3.6.1.

Устарело начиная с версии 3.9: collections.ChainMap теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.Counter(collections.Counter, Dict[T, int])

Обобщённая версия collections.Counter.

Добавлена в версии 3.5.4.

Добавлена в версии 3.6.1.

Устарело начиная с версии 3.9: collections.Counter теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

class typing.Deque(deque, MutableSequence[T])

Обобщённая версия collections.deque.

Добавлена в версии 3.5.4.

Добавлена в версии 3.6.1.

Устарело начиная с версии 3.9: collections.deque теперь поддерживает []. См. PEP 585 и Тип обобщенного псевдонима.

Другие конкретные типы

class typing.IO
class typing.TextIO
class typing.BinaryIO

Обобщённый тип IO[AnyStr] и его подклассы TextIO(IO[str]) и BinaryIO(IO[bytes]) представляют типы потоков ввода/вывода, такие как возвращаемые функцией open().

Устаревшее с версии 3.8, будет удалено в версии 3.12: Эти типы также находятся в пространстве имён typing.io, которое никогда не поддерживалось проверяющими типов и будет удалено.

class typing.Pattern
class typing.Match

Эти псевдонимы типов соответствуют типам возвращаемых значений из re.compile() и re.match(). Эти типы (и соответствующие функции) обобщены по AnyStr и могут быть сделаны конкретными, написав Pattern[str], Pattern[bytes], Match[str], или Match[bytes].

Устаревшее с версии 3.8, будет удалено в версии 3.12: Эти типы также находятся в пространстве имён typing.re , которое никогда не поддерживалось проверяющими типов и будет удалено.

Устаревшее с версии 3.9: Классы Pattern и Match из re теперь поддерживают []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Text

Text является псевдонимом для str. Он предоставляется для обеспечения обратной совместимости с кодом Python 2: в Python 2, Text является псевдонимом для unicode.

Используйте Text для указания того, что значение должно содержать строку Unicode способом, совместимым как с Python 2, так и с Python 3:

def add_unicode_checkmark(text: Text) -> Text:
    return text + u' \u2713'

Добавлен в версии 3.5.2.

Абстрактные базовые классы

Соответствующие коллекциям в collections.abc

class typing.AbstractSet(Sized, Collection[T_co])

Обобщённая версия collections.abc.Set.

Устарело начиная с версии 3.9: collections.abc.Set теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.ByteString(Sequence[int])

Обобщённая версия collections.abc.ByteString.

Этот тип представляет типы bytes, bytearray и memoryview последовательностей байтов.

В качестве сокращённого обозначения для этого типа можно использовать bytes для аннотирования аргументов любого из перечисленных выше типов.

Устарело начиная с версии 3.9: collections.abc.ByteString теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Collection(Sized, Iterable[T_co], Container[T_co])

Обобщённая версия collections.abc.Collection

Введено в версии 3.6.0.

Устарело начиная с версии 3.9: collections.abc.Collection теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Container(Generic[T_co])

Обобщённая версия collections.abc.Container.

Устарело начиная с версии 3.9: collections.abc.Container теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.ItemsView(MappingView, Generic[KT_co, VT_co])

Обобщённая версия collections.abc.ItemsView.

Устарело начиная с версии 3.9: collections.abc.ItemsView теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.KeysView(MappingView[KT_co], AbstractSet[KT_co])

Обобщённая версия collections.abc.KeysView.

Устарело начиная с версии 3.9: collections.abc.KeysView теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Mapping(Sized, Collection[KT], Generic[VT_co])

Обобщённая версия collections.abc.Mapping. Этот тип может быть использован следующим образом:

def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
    return word_list[word]

Устарело начиная с версии 3.9: collections.abc.Mapping теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.MappingView(Sized, Iterable[T_co])

Обобщённая версия collections.abc.MappingView.

Устарело начиная с версии 3.9: collections.abc.MappingView теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.MutableMapping(Mapping[KT, VT])

Обобщённая версия collections.abc.MutableMapping.

Устарело начиная с версии 3.9: collections.abc.MutableMapping теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.MutableSequence(Sequence[T])

Обобщённая версия collections.abc.MutableSequence.

Устарело начиная с версии 3.9: collections.abc.MutableSequence теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.MutableSet(AbstractSet[T])

Обобщённая версия collections.abc.MutableSet.

Устарело начиная с версии 3.9: collections.abc.MutableSet теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Sequence(Reversible[T_co], Collection[T_co])

Обобщённая версия collections.abc.Sequence.

Устарело начиная с версии 3.9: collections.abc.Sequence теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.ValuesView(MappingView[VT_co])

Обобщённая версия collections.abc.ValuesView.

Устарело начиная с версии 3.9: collections.abc.ValuesView теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

END_OF_DOCUMENT_MARKER

Соответствие другим типам в collections.abc

class typing.Iterable(Generic[T_co])

Обобщённая версия collections.abc.Iterable.

Устарело начиная с версии 3.9: collections.abc.Iterable теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Iterator(Iterable[T_co])

Обобщённая версия collections.abc.Iterator.

Устарело начиная с версии 3.9: collections.abc.Iterator теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Generator(Iterator[T_co], Generic[T_co, T_contra, V_co])

Генератор может быть аннотирован обобщённым типом Generator[YieldType, SendType, ReturnType]. Например:

def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
        sent = yield round(sent)
    return 'Done'

Обратите внимание, что в отличие от многих других обобщений в модуле 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.

class typing.Reversible(Iterable[T_co])

Обобщённая версия collections.abc.Reversible.

Устарело начиная с версии 3.9: collections.abc.Reversible теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Sized

Псевдоним для collections.abc.Sized.

Асинхронное программирование

class typing.Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co])

Обобщённая версия collections.abc.Coroutine. Изменение вариативности и порядок параметров типов соответствует значениям Generator, например:

from collections.abc import Coroutine
c: Coroutine[list[str], str, int]  # Some coroutine defined elsewhere
x = c.send('hi')                   # Inferred type of 'x' is list[str]
async def bar() -> None:
    y = await c                    # Inferred type of 'y' is int

Добавлена в версии 3.5.3.

Устарело начиная с версии 3.9: collections.abc.Coroutine теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra])

Асинхронный генератор может быть аннотирован обобщённым типом AsyncGenerator[YieldType, SendType]. Например:

async def echo_round() -> AsyncGenerator[int, float]:
    sent = yield 0
    while sent >= 0.0:
        rounded = await round(sent)
        sent = yield rounded

В отличие от обычных генераторов, асинхронные генераторы не могут возвращать значение, поэтому параметра типа ReturnType нет. Как и в случае с Generator, SendType имеет контравариантную семантику.

Если ваш генератор будет только возвращать значения, установите SendType в None:

async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
    while True:
        yield start
        start = await increment(start)

В качестве альтернативы, аннотируйте ваш генератор, указав тип возвращаемого значения как AsyncIterable[YieldType] или AsyncIterator[YieldType]:

async def infinite_stream(start: int) -> AsyncIterator[int]:
    while True:
        yield start
        start = await increment(start)

Добавлена в версии 3.6.1.

Устарело начиная с версии 3.9: collections.abc.AsyncGenerator теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncIterable(Generic[T_co])

Обобщённая версия collections.abc.AsyncIterable.

Добавлена в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.AsyncIterable теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncIterator(AsyncIterable[T_co])

Обобщённая версия collections.abc.AsyncIterator.

Добавлена в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.AsyncIterator теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.Awaitable(Generic[T_co])

Обобщённая версия collections.abc.Awaitable.

Добавлена в версии 3.5.2.

Устарело начиная с версии 3.9: collections.abc.Awaitable теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

Типы менеджеров контекста

class typing.ContextManager(Generic[T_co])

Обобщённая версия contextlib.AbstractContextManager.

Добавлена в версии 3.5.4.

Добавлена в версии 3.6.0.

Устарело начиная с версии 3.9: contextlib.AbstractContextManager теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

class typing.AsyncContextManager(Generic[T_co])

Обобщённая версия contextlib.AbstractAsyncContextManager.

Добавлена в версии 3.5.4.

Добавлена в версии 3.6.2.

Устарело начиная с версии 3.9: contextlib.AbstractAsyncContextManager теперь поддерживает []. См. PEP 585 и Тип обобщённого псевдонима.

Протоколы

Эти протоколы помечены декоратором runtime_checkable().

class typing.SupportsAbs

ABC с одним абстрактным методом __abs__ с ковариантным типом возвращаемого значения.

class typing.SupportsBytes

ABC с одним абстрактным методом __bytes__.

class typing.SupportsComplex

ABC с одним абстрактным методом __complex__.

class typing.SupportsFloat

ABC с одним абстрактным методом __float__.

class typing.SupportsIndex

ABC с одним абстрактным методом __index__.

Добавлена в версии 3.8.

class typing.SupportsInt

ABC с одним абстрактным методом __int__.

class typing.SupportsRound

ABC с одним абстрактным методом __round__ с ковариантным типом возвращаемого значения.

Функции и декораторы

typing.cast(typ, val)

Преобразование значения к типу.

Возвращает значение без изменений. Для анализа типов это сигнализирует, что возвращаемое значение имеет указанный тип, но во время выполнения ничего не проверяется (чтобы это было максимально быстро).

@typing.overload

Декоратор @overload позволяет описывать функции и методы, которые поддерживают несколько различных комбинаций типов аргументов. Последовательность определений, помеченных декоратором @overload, должна быть завершена ровно одним определением без этого декоратора (для одной и той же функции/метода). Определения с декоратором @overload предназначены только для анализа типов, так как они будут перезаписаны неописанным определением, которое используется во время выполнения, но должно игнорироваться анализатором типов. При вызове функции, помеченной декоратором @overload, напрямую будет выброшено исключение NotImplementedError. Пример перегрузки, которая даёт более точный тип, чем можно выразить с помощью объединения или переменной типа:

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>

Подробности и сравнение с другими семантиками типов см. в PEP 484.

@typing.final

Декоратор, который указывает анализаторам типов, что помеченный метод не может быть переопределён, а помеченный класс не может быть унаследован. Например:

class Base:
    @final
    def done(self) -> None:
        ...
class Sub(Base):
    def done(self) -> None:  # Error reported by type checker
        ...

@final
class Leaf:
    ...
class Other(Leaf):  # Error reported by type checker
    ...

Проверки этих свойств во время выполнения нет. Более подробная информация в PEP 591.

Добавлена в версии 3.8.

@typing.no_type_check

Декоратор, указывающий, что аннотации не являются подсказками типов.

Работает как декоратор класса или функции. Применительно к классу, применяется рекурсивно ко всем методам, определённым в этом классе (но не к методам, определённым в его родительских или дочерних классах).

Изменяет функцию(и) на месте.

@typing.no_type_check_decorator

Декоратор, который придаёт другому декоратору эффект no_type_check().

Оборачивает декоратор чем-то, что оборачивает декорируемую функцию в no_type_check().

@typing.type_check_only

Декоратор, предназначенный для того, чтобы пометить класс или функцию как недоступную во время выполнения.

Этот декоратор сам по себе недоступен во время выполнения. Он в основном предназначен для помечания классов, определённых в файлах заглушек типов, если реализация возвращает экземпляр частного класса:

@type_check_only
class Response:  # private or not available at runtime
    code: int
    def get_header(self, name: str) -> str: ...

def fetch_response() -> Response: ...

Обратите внимание, что возвращение экземпляров частных классов не рекомендуется. Обычно предпочтительнее сделать такие классы общедоступными.

Вспомогательные функции интроспекции

typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False)

Возвращает словарь, содержащий подсказки типов для функции, метода, модуля или объекта класса.

Это часто то же самое, что и obj.__annotations__. Кроме того, ссылки вперёд, закодированные в строковых литералах, обрабатываются путём их оценки в пространствах имён globals и locals. При необходимости, Optional[t] добавляется для аннотаций функций и методов, если задано значение по умолчанию, равное None. Для класса C, возвращается словарь, составленный путём объединения всех __annotations__ в обратном порядке.

Функция рекурсивно заменяет все Annotated[T, ...] на T, если include_extras не установлено в True (см. Annotated для получения дополнительной информации). Например:

class Student(NamedTuple):
    name: Annotated[str, 'some marker']

get_type_hints(Student) == {'name': str}
get_type_hints(Student, include_extras=False) == {'name': str}
get_type_hints(Student, include_extras=True) == {
    'name': Annotated[str, 'some marker']
}

Изменено в версии 3.9: Добавлен параметр include_extras в рамках PEP 593.

typing.get_args(tp)
typing.get_origin(tp)

Предоставляет основные возможности интроспекции для типов с параметрами и специальных форм типизации.

Для объекта типа `typing` вида X[Y, Z, ...] эти функции возвращают X и (Y, Z, ...). Если `obj` — это обобщённый псевдоним для встроенного или collections класса, он нормализуется до исходного класса. Если `obj` — это Union или Literal, содержащиеся в другом типе с параметрами, порядок (Y, Z, ...) может отличаться от порядка исходных аргументов [Y, Z, ...] из-за кеширования типов. Для неподдерживаемых объектов возвращаются None и () соответственно. Примеры:

assert get_origin(Dict[str, int]) is dict
assert get_args(Dict[int, str]) == (int, str)

assert get_origin(Union[int, str]) is Union
assert get_args(Union[int, str]) == (int, str)

Добавлена в версии 3.8.

class typing.ForwardRef

Класс, используемый для внутреннего представления типов в виде ссылок вперёд в виде строк. Например, List["SomeClass"] неявно преобразуется в List[ForwardRef("SomeClass")]. Пользователь не должен создавать экземпляры этого класса, но он может использоваться средствами интроспекции.

Примечание

Обобщённые типы, такие как list["SomeClass"], согласно PEP 585, не будут неявно преобразованы в 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.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/typing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API