Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про TypeScript: generics, typing, type hints, type variables, parametric polymorphism

Как используются дженерики в Python через typing?

Вопрос проверяет понимание дженериков (Generics) в Python для создания гибких и типобезопасных функций и классов, работающих с разными типами данных.

Короткий ответ

Дженерики в Python позволяют создавать функции, классы или структуры данных, которые могут работать с разными типами, сохраняя информацию о типе для проверок и подсказок. Они реализуются через модуль `typing` с использованием `TypeVar` и дженерик-классов, таких как `List[T]` или `Dict[K, V]`. Это помогает статическим анализаторам, таким как mypy, проверять корректность использования типов, не теряя гибкости кода. Например, можно написать функцию, которая возвращает список элементов любого типа, но одного и того же.

Длинный ответ

Дженерики (Generics) в Python — это механизм, который позволяет определять функции, классы или структуры данных, способные работать с различными типами, при этом сохраняя информацию о конкретном типе для статических проверок. Они реализуются через модуль typing, который вводит аннотации типов, поддерживающие параметрический полиморфизм.

Основные компоненты дженериков

Ключевые элементы для создания дженериков:

  • TypeVar: Определяет переменную типа, которая может быть заменена конкретным типом при использовании.
  • Дженерик-классы: Например, List[T], Dict[K, V] из модуля typing или пользовательские классы, наследующие от Generic[T].
  • Аннотации: Указание дженерик-типов в сигнатурах функций и классов.

Примеры использования

Рассмотрим простой пример функции, которая возвращает первый элемент списка любого типа:

from typing import TypeVar, List

T = TypeVar('T')  # Определяем переменную типа

def first_element(items: List[T]) -> T:
    """Возвращает первый элемент списка."""
    return items[0]

# Использование
numbers: List[int] = [1, 2, 3]
result: int = first_element(numbers)  # mypy понимает, что result имеет тип int
print(result)  # 1

Здесь T — это переменная типа, которая связывает тип элементов списка с типом возвращаемого значения. При вызове с List[int] функция возвращает int.

Создание дженерик-класса

Можно создавать собственные классы, которые параметризуются типами. Например, простой контейнер:

from typing import Generic, TypeVar

T = TypeVar('T')

class Box(Generic[T]):
    def __init__(self, content: T) -> None:
        self.content = content
    
    def get_content(self) -> T:
        return self.content

# Использование
box_int: Box[int] = Box(42)
value: int = box_int.get_content()  # Тип value выводится как int

box_str: Box[str] = Box("hello")
text: str = box_str.get_content()   # Тип text выводится как str

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

Где применяются дженерики

Дженерики особенно полезны в следующих сценариях:

  • Библиотеки и фреймворки: Например, в FastAPI для типизации запросов и ответов, или в ORM для типизированных запросов к базе данных.
  • Структуры данных: Реализация стеков, очередей, деревьев, которые должны работать с разными типами элементов.
  • Функции высшего порядка: Функции, принимающие другие функции (callback) с типизированными аргументами и возвращаемыми значениями.
  • Утилиты для обработки данных: Функции для маппинга, фильтрации, редукции коллекций.

Ограничения и продвинутые возможности

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

from typing import TypeVar, List

# T должен быть подтипом float или int (числовой тип)
Numeric = TypeVar('Numeric', int, float)

def sum_values(values: List[Numeric]) -> Numeric:
    return sum(values)

# Корректно
sum_values([1, 2, 3])   # int
sum_values([1.5, 2.5])  # float

# Ошибка типа (если проверить mypy): str не входит в int/float
# sum_values(["a", "b"])

Также можно использовать typing.Generic с несколькими параметрами, например, для словаря: Dict[K, V].

Вывод: Дженерики в Python через модуль typing стоит применять, когда нужно создать гибкий, повторно используемый код, который должен оставаться типобезопасным. Они особенно полезны в библиотеках, фреймворках и любом проекте, где используется статическая проверка типов (mypy, pyright), так как помогают избежать ошибок типа и улучшают читаемость кода.

Уровень

  • Рейтинг:

    3

  • Сложность:

    5

Навыки

  • TypeScript

    TypeScript

  • Python

    Python

Ключевые слова

#generics

#typing

#type hints

#type variables

#parametric polymorphism

Подпишись на Python Developer в телеграм