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

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

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

Примечание

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


Модуль обеспечивает поддержку подсказок типов во время выполнения в соответствии с указаниями PEP 484, PEP 526, PEP 544, PEP 586, PEP 589 и PEP 591. Наиболее фундаментальная поддержка состоит из типов Any, Union, Tuple, Callable, TypeVar и Generic. Полную спецификацию см. в разделе PEP 484. Упрощенное введение в советы по типированию см. в разделе PEP 483.

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

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

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

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

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

from typing import List
Vector = List[float]

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

# typechecks; список floats квалифицируется как Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])

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

from typing import Dict, Tuple, Sequence

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

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

# Средство проверки статического типа будет рассматривать предыдущий тип сигнатуры
# как точный эквивалент этому типу.
def broadcast_message(
        message: str,
        servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    ...

Следует отметить, что None как подсказка типа является частным случаем и заменяется type(None).

NewType

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

from typing import NewType

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

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

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

# typechecks
user_a = get_user_name(UserId(42351))

# не проверяет тип; int не является UserId
user_b = get_user_name(-1)

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

# 'output' имеет тип 'int', а не 'UserId'
output = UserId(23413) + UserId(54341)

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

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

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

from typing import NewType

UserId = NewType('UserId', int)

# Сбой во время выполнения и не выполняет typecheck
class AdminUserId(UserId): pass

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

from typing import NewType

UserId = NewType('UserId', int)

ProUserId = NewType('ProUserId', UserId)

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

Дополнительные сведения см. в разделе PEP 484.

Примечание

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

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

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

Вызываемый

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

Например:

from typing import Callable

def feeder(get_next_item: Callable[[], str]) -> None:
    # Тело

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    # Тело

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

Дженерики

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

from typing import Mapping, Sequence

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

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

from typing import Sequence, TypeVar

T = TypeVar('T')      # Объявить переменную типа

def first(l: Sequence[T]) -> T:   # Универсальная функция
    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 typing import Iterable

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

Универсальный тип может иметь любое количество переменных типа, и переменные типа могут быть ограничены:

from typing import TypeVar, Generic
...

T = TypeVar('T')
S = TypeVar('S', int, str)

class StrangePair(Generic[T, S]):
    ...

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

from typing import TypeVar, Generic
...

T = TypeVar('T')

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

С помощью Generic можно использовать несколько наследований:

from typing import TypeVar, Generic, Sized

T = TypeVar('T')

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

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

from typing import TypeVar, Mapping

T = TypeVar('T')

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

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

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

from typing import Iterable

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

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

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

# Тип возврата здесь такой же, как Union[Iterable[str], int]
def response(query: str) -> Response[str]:
    ...

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

def inproduct(v: Vec[T]) -> T: # 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 = None    # type: Any
a = []      # OK
a = 2       # OK

s = ''      # type: str
s = a       # OK

def foo(item: Any) -> int:
    # Typechecks; Элемент может быть любым типом,
    # и этот тип может иметь метод bar
    item.bar()
    ...

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

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

def legacy_parser(text):
    ...
    return data

# Средство проверки статического типа будет рассматривать вышеуказанное как
# имеющее ту же сигнатура, что и:
def legacy_parser(text: Any) -> Any:
    ...
    return data

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

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

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

def hash_a(item: object) -> int:
    # Терпит неудачу; объект не имеет метода "magic".
    item.magic()
    ...

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

# Typechecks, так как ints и strs являются подклассы объекта
hash_a(42)
hash_a("foo")

# Typechecks, так как Any совместим со всеми типами
hash_b(42)
hash_b("foo")

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

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

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

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

from typing import Sized, Iterable, Iterator

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

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

from typing import Iterator, Iterable

class Bucket:  # Примечание: базовые классы отсутствуют
    ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[int]: ...

def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket())  # Проходит проверку типа

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

Классы, функции и декораторы

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

class typing.TypeVar

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

Применение:

T = TypeVar('T')  # Может быть что угодно
A = TypeVar('A', str, bytes)  # Должно быть str или bytes

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

def repeat(x: T, n: int) -> Sequence[T]:
    """Возвращает список, содержащий n ссылок на x."""
    return [x]*n

def longest(x: A, y: A) -> A:
    """Возвращает самую длинную из двух строк."""
    return x if len(x) >= len(y) else y

Сигнатура последнего примера является, по существу, перегрузкой (str, str) -> str и (bytes, bytes) -> bytes. Также следует отметить, что если аргументы являются сущности некоторых подкласс str, тип возвращает по-прежнему является простой str.

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

Переменные типа могут быть помечены как ковариантные или контравариантные путем передачи covariant=True или contravariant=True. Дополнительные сведения см. в разделе PEP 484. По умолчанию переменные типа являются инвариантными. Альтернативно, переменная типа может задавать верхнюю границу, используя bound=<type>. Это означает, что фактический тип, замененный (явно или неявно) переменной типа, должен быть подкласс граничного типа, см. PEP 484.

class typing.Generic

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

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

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

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

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

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

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

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

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

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

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

func(C())  # Проходит статическая проверка типа

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

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

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

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

class typing.Type(Generic[CT_co])

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

a = 3         # Имеет тип 'int'
b = int       # Имеет тип 'Type[int]'
c = type(a)   # Также имеет тип 'Type[int]'

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

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

# Принимает User, BasicUser, ProUser, TeamUser, ...
def make_new_user(user_class: Type[User]) -> User:
    # ...
    return user_class()

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

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

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

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

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

class typing.Iterable(Generic[T_co])

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

class typing.Iterator(Iterable[T_co])

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

class typing.Reversible(Iterable[T_co])

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

class typing.SupportsInt

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

class typing.SupportsFloat

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

class typing.SupportsComplex

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

class typing.SupportsBytes

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

class typing.SupportsIndex

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

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

class typing.SupportsAbs

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

class typing.SupportsRound

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

class typing.Container(Generic[T_co])

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

class typing.Hashable

Это алиас к collections.abc.Hashable

class typing.Sized

Это алиас к collections.abc.Sized

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

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

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

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

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

class typing.MutableSet(AbstractSet[T])

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

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

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

def get_position_in_index(word_list: Mapping[str, int], word: str) -> int:
    return word_list[word]
class typing.MutableMapping(Mapping[KT, VT])

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

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

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

class typing.MutableSequence(Sequence[T])

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

class typing.ByteString(Sequence[int])

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

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

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

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

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

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

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

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

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

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

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

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

def keep_positives(vector: Sequence[T]) -> List[T]:
    return [item for item in vector if item > 0]
class typing.Set(set, MutableSet[T])

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

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

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

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

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

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

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

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

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

class typing.ValuesView(MappingView[VT_co])

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

class typing.Awaitable(Generic[T_co])

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

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

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

Общая версия collections.abc.Coroutine. Дисперсия и порядок переменных типа соответствуют, например, переменным Generator:

from typing import List, Coroutine
c = None # type: Coroutine[List[str], str, int]
...
x = c.send('hi') # type: List[str]
async def bar() -> None:
    x = await c # type: int

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

class typing.AsyncIterable(Generic[T_co])

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

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

class typing.AsyncIterator(AsyncIterable[T_co])

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

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

class typing.ContextManager(Generic[T_co])

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

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

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

class typing.AsyncContextManager(Generic[T_co])

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

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

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

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

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

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

def count_words(text: str) -> Dict[str, int]:
    ...
class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Заметим, что в отличие от многих других дженериков в модуле typing, SendType Generator ведет себя контравариантно, а не ковариационно или инвариантно.

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

def infinite_stream(start: int) -> Generator[int, None, None]:
    while True:
        yield start
        start += 1

Можно также аннотировать генератор как имеющие тип возвращает Iterable[YieldType] или Iterator[YieldType]:

def infinite_stream(start: int) -> Iterator[int]:
    while True:
        yield start
        start += 1
class typing.AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra])

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

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

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

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

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

Можно также аннотировать генератор как имеющие тип возвращает AsyncIterable[YieldType] или AsyncIterator[YieldType]:

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

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

class typing.Text

Text - это алиас для str. Предусмотрена подача прямого совместимого пути для Python 2 кода: в Python 2 Text является алиасом для unicode.

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

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

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

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

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

class typing.Pattern
class typing.Match

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

class typing.NamedTuple

Типизированная версия collections.namedtuple().

Применение:

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

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

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

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

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

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

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

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

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

class Employee(NamedTuple):
    """Представляет сотрудника."""
    name: str
    id: int = 3

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

Использование с обратной совместимостью:

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

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

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

Deprecated since version 3.8, will be removed in version 3.9: Обесценил _field_types атрибут в пользу более стандартного __annotations__ атрибут, который имеет ту же информацию.

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

class typing.TypedDict(dict)

Простое типизированное пространство имен. Во время выполнения он эквивалентен простому dict.

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

class Point2D(TypedDict):
    x: int
    y: int
    label: str

a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
b: Point2D = {'z': 3, 'label': 'bad'}           # Не удалось проверить тип

assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')

Информация о типе для внутреннего анализа доступна через Point2D.__annotations__ и Point2D.__total__. Чтобы разрешить использование этой функции со старыми версиями Python, не поддерживающими PEP 526, TypedDict поддерживает две дополнительные эквивалентные синтаксические формы:

Point2D = TypedDict('Point2D', x=int, y=int, label=str)
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

По умолчанию все ключи должны присутствовать в TypedDict. Это можно переопределить, указав множество. Использование:

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

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

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

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

class typing.ForwardRef

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

typing.NewType(typ)

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

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

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

typing.cast(typ, val)

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

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

typing.get_type_hints(obj[, globals[, locals]])

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

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

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

Обеспечить базовый самоанализ для универсальных типов и специальных форм ввода.

Для объекта ввода формы X[Y, Z, ...] эти функции возвращает X и (Y, Z, ...). Если X является базовым алиас для класса builtin или collections, он нормализуется к исходному классу. Для неподдерживаемых объектов возвращает None и () соответственно. Примеры:

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

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

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

@typing.overload

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

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

Дополнительные сведения и сравнение с другими семантиками ввода см. в разделе PEP 484.

@typing.final

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

class Base:
    @final
    def done(self) -> None:
        ...
class Sub(Base):
    def done(self) -> None:  # Ошибка, указанная средством проверки типа
          ...

@final
class Leaf:
    ...
class Other(Leaf):  # Ошибка, указанная средством проверки типа
    ...

Проверка этих свойств во время выполнения отсутствует. Дополнительные сведения см. в разделе PEP 591.

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

@typing.no_type_check

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

Это работает как декоратор класса или функции. С классом он применяется рекурсивно ко всем методам, определенным в этом классе (но не к методам, определенным в его суперклассы или подклассы).

Это мутирует существующую функцию (функции).

@typing.no_type_check_decorator

Декоратор, чтобы дать другому декоратору эффект no_type_check().

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

@typing.type_check_only

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

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

@type_check_only
class Response:  # частный или недоступный во время выполнения
    code: int
    def get_header(self, name: str) -> str: ...

def fetch_response() -> Response: ...

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

@typing.runtime_checkable

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

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

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

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

Предупреждение: это будет проверять только наличие требуемых методов, а не их сигнатуры типа!

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

typing.Any

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

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

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

from typing import NoReturn

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

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

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

typing.Union

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

Для определения объединения используйте, например, Union[int, str]. Подробнее:

  • Аргументы должны быть типами, и должен быть хотя бы один.

  • Союзы сплющенных союзов, например,:

    Union[Union[int, str], float] == Union[int, str, float]
    
  • Союзы одного аргумента исчезают, например:

    Union[int] == int # конструктор фактически возвращает int
    
  • Избыточные аргументы пропускаются, например:

    Union[int, str, int] == Union[int, str]
    
  • При сравнении союзов порядок аргументов игнорируется, например,:

    Union[int, str] == Union[str, int]
    
  • Нельзя подкласс или создать экземпляр объединения.

  • Ты не можешь писать Union[X][Y].

  • Optional[X] можно использовать в качестве краткого текста для Union[X, None].

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

typing.Optional

Дополнительный тип.

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

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

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

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

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

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

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

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

typing.Callable

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

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

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

typing.Literal

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

def validate_simple(data: Any) -> Literal[True]:  # всегда возвращает True
    ...

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

open_helper('/some/path', 'r')  # Проходит проверку типа
open_helper('/other/path', 'typo')  # Ошибка при проверке типа

Literal[...] не могут быть подклассированы. Во время выполнения в качестве аргумента типа для Literal[...] допускается произвольное значение, но проверки типа могут накладывать ограничения. Дополнительные сведения о типах PEP 586 см. в разделе литерал.

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

typing.ClassVar

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

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

class Starship:
    stats: ClassVar[Dict[str, int]] = {} # переменная класса
    damage: int = 10                     # сущность переменная

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

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

enterprise_d = Starship(3000)
enterprise_d.stats = {} # Ошибка при установке переменной класса для сущности
Starship.stats = {}     # Все в порядке

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

typing.Final

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

MAX_SIZE: Final = 9000
MAX_SIZE += 1  # Ошибка, указанная средством проверки типа

class Connection:
    TIMEOUT: Final[int] = 10

class FastConnector(Connection):
    TIMEOUT = 1  # Ошибка, указанная средством проверки типа

Проверка этих свойств во время выполнения отсутствует. Дополнительные сведения см. в разделе PEP 591.

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

typing.AnyStr

AnyStr - переменная типа, определенная как AnyStr = TypeVar('AnyStr', str, bytes).

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

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

concat(u"foo", u"bar")  # ОК, вывод имеет тип 'unicode'
concat(b"foo", b"bar")  # ОК, вывод имеет тип 'bytes'
concat(u"foo", b"bar")  # Ошибка, не удается смешать Юникод и байты
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 из среды выполнения интерпретатор. Аннотации типа для локальная переменных не вычисляются, поэтому вторую аннотацию не нужно заключать в кавычки.

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