Spec-Zone.ru › Python 3.8

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; a list of floats qualifies as a 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:
    ...

# 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 typing 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

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

Обобщённые типы

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

from typing import Mapping, Sequence

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

Обобщённые типы могут быть параметризованы с помощью нового фабричного метода, доступного в typing, — TypeVar.

from typing import Sequence, 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 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]

# 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 = None    # type: Any
a = []      # OK
a = 2       # OK

s = ''      # type: 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 и отличается от того, что обычно делается в типичном динамически типизированном коде 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:  # 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, пользователь может определить новые пользовательские протоколы для полного использования структурного подтипирования (см. примеры ниже).

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

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

class typing.TypeVar

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

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

T = TypeVar('T')  # Can be anything
A = TypeVar('A', str, bytes)  # Must be str or bytes

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

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

def longest(x: A, y: A) -> A:
    """Return the longest of two strings."""
    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:
        ...
        # 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.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.

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.

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.

END_OF_DOCUMENT_MARKER
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 ведет себя контравариантно, а не ковариантно или инвариантно.

Если ваш генератор будет только возвращать значения, установите 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 ведет себя контравариантно.

Если ваш генератор будет только возвращать значения, установите 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 для указания того, что значение должно содержать строку Unicode таким образом, чтобы оно было совместимо с 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]) представляют типы потоков ввода-вывода, возвращаемых функцией open().

class typing.Pattern
class typing.Match

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

END_OF_DOCUMENT_MARKER
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, будет удалено в версии 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'}           # Fails type check

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

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

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

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

class typing.ForwardRef

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

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

typing.NewType(name, tp)

Вспомогательная функция для обозначения отличного типа для средства проверки типов, см. 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 и X. Если X является универсальным псевдонимом для встроенного или класса 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, напрямую приведет к исключению 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.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 совместим с каждым типом.
END_OF_DOCUMENT_MARKER
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  # 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.Tuple

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

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

Для указания кортежа переменной длины однородного типа используйте литеральную эллипсис, например, 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]:  # always returns True
    ...

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

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

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

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

typing.ClassVar

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

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

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

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

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

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

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

typing.Final

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

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

class Connection:
    TIMEOUT: Final[int] = 10

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

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

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

typing.AnyStr

AnyStr — это переменная типа, определенная как 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
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.

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

Spec-Zone.ru

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