← Назад к вопросам
Используешь ли Generic из библиотеки typing в Python
2.0 Middle🔥 231 комментариев
#Безопасность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Да, активно использую Generics
Generics из typing — это один из самых мощных инструментов для написания типобезопасного и гибкого кода на Python. Я использую их повседневно при работе с контейнерами, функциями и классами.
Основные применения
Контейнеры с типизацией
from typing import List, Dict, Set, Tuple
# Перечисляем тип элементов контейнера
users: List[str] = ["Alice", "Bob"]
scores: Dict[str, int] = {"Alice": 100, "Bob": 85}
usernames: Set[str] = {"Alice", "Bob"}
coords: Tuple[int, int] = (10, 20)
Функции с параметрами-типами
from typing import TypeVar, Generic
T = TypeVar("T") # Переменная типа
def get_first(items: List[T]) -> T:
"""Возвращает первый элемент, сохраняя тип."""
return items[0]
# IDE поймёт, что result — это str
result: str = get_first(["hello", "world"])
Собственные Generic классы
from typing import Generic, TypeVar
T = TypeVar("T")
class Stack(Generic[T]):
def __init__(self):
self.items: List[T] = []
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
return self.items.pop()
# Использование
int_stack: Stack[int] = Stack()
int_stack.push(42)
value: int = int_stack.pop()
Сложные сценарии
Ограничения типов (Bounded TypeVar)
from typing import TypeVar
Comparable = TypeVar("Comparable", int, float, str)
def max_value(a: Comparable, b: Comparable) -> Comparable:
return a if a > b else b
Multiple constraints
K = TypeVar("K", str, int) # Ключ может быть str или int
V = TypeVar("V") # Значение — любого типа
class Cache(Generic[K, V]):
def __init__(self):
self._data: Dict[K, V] = {}
Python 3.9+ синтаксис
С Python 3.9 можно использовать встроенные типы напрямую без typing:
# Старый способ (Python < 3.9)
from typing import List, Dict
users: List[str] = []
# Новый способ (Python 3.9+)
users: list[str] = []
scores: dict[str, int] = {}
Реальный пример: Repository паттерн
from typing import Generic, TypeVar, List, Optional
from sqlalchemy.orm import Session
T = TypeVar("T")
class Repository(Generic[T]):
def __init__(self, db: Session, model: type[T]):
self.db = db
self.model = model
def get_all(self) -> List[T]:
return self.db.query(self.model).all()
def get_by_id(self, id: int) -> Optional[T]:
return self.db.query(self.model).filter(self.model.id == id).first()
def create(self, obj: T) -> T:
self.db.add(obj)
self.db.commit()
return obj
class User:
id: int
name: str
user_repo: Repository[User] = Repository(db, User)
users: List[User] = user_repo.get_all()
Преимущества
- IDE поддержка: автодополнение и проверка типов работают правильно
- Меньше ошибок: IDE и mypy ловят типобезопасность на этапе разработки
- Документация: код самодокументируется
- Переиспользуемость: один Generic класс работает с любыми типами
Когда использовать
Я применяю Generics в:
- Структурах данных (стеки, очереди, деревья)
- Repository/DAO паттернах
- Обёртках для API клиентов
- Функциях-утилитах высокого уровня
Generics — это не просто best practice, это необходимость при написании масштабируемого кода.