Сообщить об ошибке.

Тип аннотации TypeGuard модуля typing в Python

Новое в Python 3.10

Тип аннотации TypeGuard модуля typing - специальная форма ввода, используемая для аннотирования типа возвращаемого значения определяемой пользователем функции защиты типа. Аннотация typing.TypeGuard принимает только один аргумент типа. Во время выполнения, функции помеченные таким образом, должны возвращать логическое значение.

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

def is_str(val: str | float):
    # функция isinstance() - защита типа аргумента `val`
    if isinstance(val, str):
        # Тип аргумента `val` сужен до `str`
        ...
    else:
        # В противном случае тип `val` сужается до `float`.
        ...

Было бы удобно использовать определяемую пользователем логическую функцию в качестве защиты типа. Такая функция должна использовать TypeGuard[...] в качестве возвращаемого типа, чтобы предупредить средства проверки статического типа об этом намерении.

Аннотация -> TypeGuard сообщает средству проверки статического типа, что для данной функции:

  • Возвращаемое значение - логическое.
  • Если возвращаемое значение - True, то тип его аргумента - это тип, переданный в качестве аргумента TypeGuard.

Например:

def is_str_list(val: List[object]) -> TypeGuard[List[str]]:
    '''Определяет, все ли объекты в списке являются строками'''
    return all(isinstance(x, str) for x in val)

def func1(val: List[object]):
    if is_str_list(val):
        # Тип `val` сужен до ``List[str]``.
        print(" ".join(val))
    else:
        # Тип `val` остается таким же ``List[object]``.
        print("Не список строк!")

Если is_str_list() - это метод класса или экземпляра, то тип в TypeGuard сопоставляется с типом второго параметра после cls или self.

Короче говоря, форма def foo(arg: TypeA) -> TypeGuard[TypeB]: ... означает, что если foo(arg) возвращает True, то arg сужается от TypeA до TypeB.

Примечание. TypeB не обязательно должен быть более узкой формой TypeA - это может быть даже более широкая форма. Основная причина состоит в том, чтобы разрешить такие вещи, как сужение List[object] до List[str], даже если последний не является подтипом первого, поскольку List инвариантен. Ответственность за написание безопасных типов защиты возлагается на пользователя.

TypeGuard также работает с переменными типа.

Новое в Python 3.10.