Spec-Zone.ru › Python 3.6

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

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

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

Примечание

Модуль typing включён в стандартную библиотеку на временной основе. Новые возможности могут быть добавлены, а API может измениться даже между младшими версиями выпуска, если этого потребуют разработчики ядра.

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

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

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

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

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

Псевдоним типа определяется присвоением типа псевдониму. В этом примере 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, List

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

def broadcast_message(message: str, servers: List[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: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    ...

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

26.1.2. 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.

26.1.3. 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].

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

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

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]

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

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

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 использует метакласс, который определяет __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)

Метакласс, используемый Generic, является подклассом abc.ABCMeta. Обобщённый класс может быть ABC путём включения абстрактных методов или свойств, и обобщённые классы также могут иметь ABC в качестве базовых классов без конфликтов метаклассов. Обобщённые метаклассы не поддерживаются. Результат параметризации обобщённых типов кэшируется, и большинство типов в модуле typing хешируемы и сравнимы по равенству.

26.1.6. Тип 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, чтобы указать, что значение имеет динамический тип.

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

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

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.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[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.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.

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.

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.6.1.

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

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

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

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.

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.

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
class typing.AsyncIterable(Generic[T_co])

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

class typing.AsyncIterator(AsyncIterable[T_co])

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

class typing.ContextManager(Generic[T_co])

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

Новая в версии 3.6.

class typing.AsyncContextManager(Generic[T_co])

Абстрактный базовый класс с асинхронными абстрактными методами __aenter__() и __aexit__().

Новая в версии 3.6.

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

Обобщённая версия dict. Использование этого типа выглядит следующим образом:

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

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

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

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

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

Новая в версии 3.6.1.

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

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

Новая в версии 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.5.4.

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].

class typing.NamedTuple

Типизированная версия 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

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

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

Классы, наследующие от NamedTuple, также могут иметь docstrings и методы:

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: Добавлены поддержка значений по умолчанию, методов и docstrings.

typing.NewType(typ)

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

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

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

typing.cast(typ, val)

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

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

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

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

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

@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.no_type_check

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

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

Этот декоратор изменяет функцию(и) на месте.

@typing.no_type_check_decorator

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

Этот декоратор обёртывает декоратор, который, в свою очередь, обёртывает декорируемую функцию в no_type_check().

typing.Any

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

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

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

from typing import NoReturn

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

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

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[int, object] == object
    
  • Нельзя создавать подклассы или экземпляры объединения.
  • Нельзя написать Union[X][Y].
  • Можно использовать Optional[X] как сокращение для Union[X, None].
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[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.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.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–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/typing.html

Spec-Zone.ru

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