def add(a: int, b: int) → int:
msg: str = f"Сумма чисел {a} и {b} = {a + b}"
print(msg)
return a + b
В данном примере мы видим функцию которая принимает два целых числа, и возвращает число. В самой функции мы создаем переменную msg и указываем что это строка.
Для аннотации типа значений аргумента используется двоеточие и после идёт указываемый тип. Для указания возвращаемого значения используется ->и после возвращаемый тип.
❗️ Заметим что Python не проверяет типы при вызове функции. Аннотации просто подсказывают тип.
Если мы вызовем add("Hello ", "World") то получим вывод "Сумма чисел Hello и World = Hello World".
Но зачем они нужны если они не влияют на код?
Это помогает другим разработчикам понимать ваш код.
Пример ситуации:
Вы создали функцию get_user которая принимает id пользователя и возвращает его объект:users = {123: "User"}
def get_user(user_id):
return users.get(user_id)
Если другой разработчик попытается передать ключ "123", функция вернет None, так как в словаря наш пользователь записан ключом 123 типа int. Если мы укажем в аннотации все данные:users: dict[int, str] = {123: "User"}
def get_user(user_id: int) -> str | None:
return users.get(user_id)Само-документирует код.
Аннотации позволят вам не указывать в документации их тип.IDE и статические анализаторы используют аннотации для проверки типов и подсказок.
Давайте рассмотрим как использовать статический анализатор mypyУстанавливаем mypy: pip install mypy.
Запускаем проверку mypy main.py или другой ваш файл или директория.
Для строгой проверки используйте флаг —strict mypy —strict main.py
Вам выведется подробное сообщение анализа.
❓Какие есть типы аннотаций?
Базовые типы.
int, str, float, bool и т.п - это всё простые типы. Они явно указывают что объект является их типом.Коллекции.
Давайте рассмотрим основные:
list - Для указания типа используются квадратные скобки. Список чисел: list[str]
tuple - Для указания точного кортежа например кортежа из трёх строк используйте такую аннотацию: tuple[str, str, str], для переменного количества аргументов используйте Ellipsis(Троеточие): tuple[str, ...]
dict - Указывается два значения, первый это тип ключа, второй это тип значения. Пример словарь строка-число dict[str, int]
set, frozenset - Аналогично list и tuple. Тип значение указывается в квадратных скобках set[str]
Другие аннотации. Для других аннотаций используется модуль typing из стандартной библиотеки
Union. Если вы хотите указать что тип может быть как одним так и другим типом используйте синтаксис int | str(Число или строка). Для старых версий Python используйте Union[int, str].
Literal. Если вы хотите указать что переменная/аргумент/функция принимает только конкретные типы из определённого списка, используйте Literal['+', '-', "*", "/"].
Optional - Если вы хотите указать что тип может быть как одним так и другим типом используйте синтаксис int | None (Число или None). ❗️ В Python 3.9 и ниже используйте Optional[int]
Any. Если вы хотите указать что переменная/аргумент/функция принимает произвольное значение, то используйте Any. ❗️ Any - спорный тип. При его использовании теряется смысл типизации. Используйте в местах где вы точно уверенны что тип произвольный. 🔥 Если вы используете аннотации из typing, не забудьте импортировать явно from typing import Optional, Union, Literal, Any или использовать точечную нотацию typing.Any
✍️ Это был первый обзор аннотаций в Python. В этом посте я покрыл не все темы аннотаций. В последующих постах я разберу как создавать свои Generic классы. Что такое Protocol и чем он отличается от абстрактных классов. Более продвинутые аннотации и как их использовать.
❗️ Если вы ещё не используете аннотации, то используйте их в своем коде!
PEP 484 — PEP про аннотации
typing — Документация typing
Binobinos — Python (https://t.me/binobinosdev) #typehints