Что такое generics в Python
Что проверяют
Умеете ли вы писать типизированный код так, чтобы анализатор помогал, а не молчал. Вопрос отделяет тех, кто расставляет аннотации по привычке, от тех, кто понимает: аннотация связывает типы между собой и проверяется отдельным инструментом, а не интерпретатором.
Как отвечать
Дженерики это параметризация типом: функция или класс описываются один раз и работают с любым типом, сохраняя связь между аргументом и результатом. Раньше переменную типа объявляли через typing, в современных версиях есть компактный синтаксис прямо в объявлении.
def first[T](items: list[T]) -> T | None:
return items[0] if items else None
class Repo[T]:
def __init__(self) -> None:
self._rows: dict[int, T] = {}
def get(self, key: int) -> T | None:
return self._rows.get(key)Уместно назвать соседние инструменты: верхняя граница и перечисление допустимых типов для переменной, Protocol вместо наследования интерфейса, ParamSpec для декораторов, обязанных сохранить сигнатуру обёрнутой функции. Стандартные контейнеры параметризуются сами, аналоги из typing больше не нужны.
Закончить стоит честным ограничением: интерпретатор аннотации не проверяет, их читает статический анализатор, и польза появляется тогда, когда он включён в CI. Проверки во время выполнения это уже другая история, например валидация моделей в pydantic.
Где спотыкаются
Подменяют переменную типа на Any. Это не «любой тип», а отключение проверки: функция начинает принимать и возвращать что угодно, а ошибка всплывает у вызывающего кода. Когда тип действительно любой, но проверка нужна, берут object и сужают его.
Используют одну переменную типа там, где нужны две. Повтор имени в сигнатуре это требование одинакового типа, поэтому функция сравнения или пары внезапно отказывается принимать строку и число. Обратная ошибка тоже частая: две переменные там, где связь обязана сохраниться.
Ждут проверок во время выполнения. Параметризованный класс не мешает положить внутрь чужой объект, а проверка принадлежности к параметризованному типу просто запрещена. Дженерики ничего не ускоряют и ни от чего не защищают сами по себе, защищает прогон анализатора.