Подсказки по типам Python — Как сузить количество типов с помощью TypeGuard

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Ранее я уже рассказывал о сужении типов с помощью isinstance(), assert и Literal. В сегодняшней заметке мы рассмотрим TypeGuard, новый специальный тип, который позволяет нам создавать кастомные функции сужения типов.

TypeGuard был определен в PEP 647 и доступен в Python 3.10+ или в более старых версиях из typing-extensions. Гвидо ван Россум добавил поддержку в Mypy в версии 0.900, которая была опубликована накануне.

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

from __future__ import annotations

name: str | None

if isinstance(name, str):
    # name must be 'str'
    ...
else:
    # name must be None
    ...

Средства проверки типов, включая Mypy, поддерживают ограниченное количество выражений, таких как if isinstance(...). Но количество потенциально сужающих тип выражений бесконечно, особенно для параметризованных типов, таких как контейнеры. TypeGuard позволяет нам написать любое выражение типа и сообщить нашему средству для проверки типов, что оно их сужает.

Сужающая тип функция — такая, которая принимает хотя бы один аргумент и возвращает bool. Вместо того чтобы обозначить возвращаемый тип как bool, мы используем TypeGuard[T], где True означает, что первый аргумент имеет тип T, а False — нет. Возьмем этот пример, адаптированный из PEP:

from __future__ import annotations

from typing_extensions import TypeGuard


def is_str_list(value: list[object]) -> TypeGuard[list[str]]:
    """Are all list items strings?"""
    return all(isinstance(x, str) for x in value)


x: list[object]

reveal_type(x)
if is_str_list(x):
    reveal_type(x)

is_str_list() возвращает True, если в заданном списке содержатся только строки. Мы сообщаем Mypy, что он может сузить тип value до list[str] с помощью возвращаемого типа TypeGuard.

Запустив Mypy на этом файле, мы видим следующий результат вызова reveal_type():

$ mypy --strict example.py
example.py:13: note: Revealed type is "builtins.list[builtins.object]"
example.py:15: note: Revealed type is "builtins.list[builtins.str]"

Второе примечание показывает, что Mypy знает, что x должен быть списком строк в блоке if. Это позволяет нам использовать элементы списка в качестве str без каких-либо ошибок. Отлично!

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

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

PEP 647 также показывает общие функции TypeGuard с TypeVar, но когда я попробовал примеры, то обнаружил, что Mypy 0.901 пока не поддерживает их. Для TypeGuard существует несколько открытых проблем, так что, похоже, Mypy может воспользоваться нашим вкладом в их решение!

И пусть ваши типы будут хорошо защищены.


Приглашаем всех желающих на открытое занятие по теме «Знакомство с веб разработкой на Flask». На этом занятии мы с вами познакомимся с основами веб-разработки на Flask, а также научимся создавать и рендерить шаблоны страниц. Попробуем создать Flask приложение, затем создать роуты и в конце обработать различные HTTP методы на Flask. Регистрация по ссылке.

Источник: https://habr.com/ru/company/otus/blog/666830/


Интересные статьи

Интересные статьи

В заголовке известная ошибка python3.Интерпретатор python2 импортирует opencv без ошибок при установке совместно с python3 в единой среде исполнения.Краткая инструкция по локализации ошибки далее.
С появлением подсказок типов (type hints) в Python 3.5+ добавилась опциональная статическая типизация – поэтому эти подсказки так мне нравятся. Теперь я аннотирую ими все мои проекты.
Статья предназначена в первую очередь для консультантов и архитекторов, работающих с продуктами SAP, перед которыми стоит задача проектирования и реализации решения по подготовке отчетности в формате ...
Привет, Хабр! представляю вашему вниманию перевод статьи «Setting up NextCloud and ONLYOFFICE on a single server with Docker». Сложно недооценивать пользу онлайновых пакетов офисных приложений...
Всем привет! Меня зовут Артур, я работаю ВКонтакте в команде мобильного веба, занимаюсь проектом VKUI — библиотекой React-компонентов, с помощью которой написаны некоторые наши интерфейсы в мобил...