Найти тему
С любовью о Python

Аннотации типов в Python

Designed by Freepik (www.freepik.com)
Designed by Freepik (www.freepik.com)

Все мы знаем, что Python - язык с динамической типизацией. Но с довольно давних пор в нем также появилась возможность явно указывать типы данных и это здорово матчится с принципом дзена Python: явное лучше неявного (Explicit is better than implicit).

Зачем их вообще указывать?

Да, аннотации являются необязательными, но я бы сказал, что это правила хорошего тона для программистов. Важно четко понимать, с чем ты работаешь. Это поможет избежать ошибок (зачастую нетривиальных), когда параметр обрабатывает несколько типов данных или принимает какие-то сложные объекты. Если вы работаете в большой команде, это просто облегчит вам жизнь.

Как указывать аннотации?

Когда мы прописываем тип данных для какого-то объекта или параметра - просто через двоеточие, для возвращаемых типов - указываем через стрелочку.

Несколько примеров:

Встроенные типы и модуль typing

name: str = "Dude"
age: int = 49
height: float = 185.1

Iterable

Для итерируемых объектов мы можем явно указать тип Iterable, когда нам не принципиально, что именно это будет - список, кортеж и т.д.

from typing import Iterable


def my_func(param: Iterable[int]) -> None:
for num in param:
print(num)

my_func(param=(1, 2, 3))
my_func(param={1, 2, 3})
my_func(param=[1, 2, 3])

Union, Optional, Any

Когда нам нужно использовать несколько типов, мы можем использовать тип Union из модуля typing, или просто символ | между типами (второе предпочтительнее).

from typing import Union


param_1: Union[str, int]
param_2: str | int

Для опциональных значений существует отдельный тип Optional или просто | None. Здесь также предпочтительно второе.

from typing import Optional


param_1: Optional[str]
param_2: str | None

Отдельно упомяну про тип Any из модуля typing. По сути он и означает то, чем является - любой тип данных. Например, если вы работаете с большим словарем с кучей вложенностей разных типов, можно просто прописать param: dict[str, Any]. Нет боли от прописывания всех типов + понятно, что работаешь с словарем. Конечно, без необходимости лучше избегать этот тип и явно прописывать то, с чем работаешь.

Возвращаемые значения

Здесь никакой магии, как и писал выше - просто указываем type hints через стрелочку:

def my_func(param1: int, param2: int) -> int:
return param1 + param2

def __init__(self, param: str) -> None:
self.param: str = param

Стоит упомянуть, что если в type hints прописан один тип данных и при этом вы работаете с другим - ошибок не будет, но IDE подсветит такие моменты.

Можно ли автоматически проверять типизацию?

Да. Для этого понадобится кое-что прикрутить к проекту. Чаще всего предпочтение отдается mypy или ruff. Так линтеры / чекеры будут стоять на страже качества кода и не придется уделять этому дополнительное внимание на код ревью.

Не бойтесь указывать аннотации типов где только возможно и мир станет чуточку лучше. :)

***

Присоединяйтесь ко мне в Telegram: https://t.me/python3_with_love. Там есть все, и читать код намного удобнее.