Подсказки типов нужны только в функциях?
В чате Telegram-канала задали отличный вопрос — подсказки типов имеет смысл ставить только для аргументов функций и возвращаемых значений или вообще для всех переменных?
И действительно. Как лучше?
В большинстве сценариев подсказок типов достаточно только для аргументов и результатов функций. Если в нашем коде все функции типизированы таким образом, то получается, что IDE и статический анализатор кода понимают тип любой переменной в коде и могут выполнять все проверки.
Объявляя переменную, мы либо задаём её значение в явном виде (и тогда тип переменной равен типу значения):
age = 33
user = User(username="Иннокентий")
Здесь тип переменной age
равен типу значения 33
, то есть int
, а тип переменной user
равен User
.
Второй вариант создания переменной — присваивание ей значения, которое возвращается функцией:
user = get_user_by_username("Иннокентий")
Если все функции в нашем коде типизированы, в том числе и функция get_user_by_username
, то и в таких сценариях тип переменной очевиден. Какой тип данных функция возвращает, такой тип данных у переменной и будет.
Получается, что если все функции, используемые в коде, типизированы, то как правило нет смысла проставлять типы для обычных переменных.
Однако, иногда бывает так, что мы используем внешнюю библиотеку, функции которой нетипизированы. Если функция get_user_by_username
в примере выше это функция внешней библиотеки и она нетипизирована, то IDE и статический анализатор кода не знают, какой тип данных вернёт эта функция и потому не знают, какой тип будет у переменной user
. Тогда можно подсказать инструментам, явно указав тип:
user: User = get_user_by_username("Иннокентий")
Теперь IDE и статический анализатор будут знать тип переменной и смогут выполнять все проверки. Отлично!
Ещё один сценарий, при котором полезно задать переменной тип — когда мы инициализируем переменную пустым значением, но хотим указать, данные какого конкретно типа там будут.
Например, в конструкторе класса мы инициализируем атрибут с начальным значением {}
, то есть пустой словарь, но указываем, что в этом словаре ключами будут строки, значениями числа. То есть мы уточняем тип данных, сужаем его с просто словаря до словаря с конкретным типом ключей и значений:
class SomeClass:
def __init__(self):
self._some_dict: dict[str, int] = {}
def some_method(self):
self._some_dict["some_key"] = 123 # Всё ок по типам
self._some_dict[123] = "some_key" # Ошибка типов!