← Назад к вопросам

Используешь ли типизацию

2.0 Middle🔥 181 комментариев
#Безопасность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типизация в Python — мой подход

Да, я активно использую типизацию в Python и считаю её одним из ключевых инструментов для написания надёжного, поддерживаемого кода. За свой 10+ лет опыт я видел, как типизация эволюционировала в Python и как её внедрение значительно улучшает качество проектов.

Почему я использую типизацию

  1. Предотвращение ошибок — Type checker (mypy, pyright, pylance) ловит многие ошибки на этапе разработки, а не в production
  2. Самодокументирующийся код — типы сразу показывают, какие данные ожидает функция
  3. IDE support — лучшая автодополнение и подсказки благодаря информации о типах
  4. Рефакторинг — когда изменяешь тип, IDE помогает найти все места, которые нужно обновить
  5. Командная разработка — новые члены команды быстрее понимают контракты функций

Базовые примеры типизации

Вот как я обычно пишу типизированный код:

from typing import List, Dict, Optional, Union

def process_users(user_ids: List[int]) -> Dict[int, str]:
    """Обработать список пользователей и вернуть словарь."""
    result: Dict[int, str] = {}
    for user_id in user_ids:
        result[user_id] = fetch_user_name(user_id)
    return result

def get_user_by_id(user_id: int) -> Optional[Dict[str, str]]:
    """Получить пользователя или None если не найден."""
    # implementation
    pass

Типизация в современном Python (3.10+)

С введением Python 3.10 и 3.11 типизация стала ещё удобнее. Я использую новый синтаксис:

from typing import Literal

def process_order(order_id: int, status: Literal["pending", "shipped", "delivered"]) -> bool:
    """Обработать заказ с определёнными статусами."""
    if status == "pending":
        send_notification(order_id)
    return True

# Union типы вместо |
def get_value(key: str) -> str | int | None:
    """Вернуть значение как строку, число или None."""
    pass

Сложные типы: Generics и Protocol

Для более сложных случаев я использую Generics и Protocol:

from typing import Generic, TypeVar, Protocol

T = TypeVar('T')

class Repository(Generic[T]):
    """Базовый репозиторий для работы с сущностями типа T."""
    
    def get(self, id: int) -> T:
        pass
    
    def save(self, entity: T) -> None:
        pass

class UserRepository(Repository[User]):
    def get(self, id: int) -> User:
        # implementation
        pass

# Protocol для duck typing
class Drawable(Protocol):
    def draw(self) -> None:
        ...

def render(obj: Drawable) -> None:
    obj.draw()

Dataclasses и TypedDict

Для структурированных данных я использую dataclasses и TypedDict:

from dataclasses import dataclass
from typing import TypedDict

@dataclass
class User:
    id: int
    name: str
    email: str
    is_active: bool = True

class UserDict(TypedDict):
    id: int
    name: str
    email: str

def create_user(data: UserDict) -> User:
    return User(**data)

Type checking tools

В своих проектах я использую:

  • mypy — классический type checker, строгий и надёжный
  • pyright/pylance — быстрый и интегрируется с VS Code
  • pydantic — валидация типов в runtime, особенно для API

Обычно конфиг выглядит так:

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
no_implicit_optional = true

Pydantic для runtime validation

Для API и внешних данных я использую Pydantic:

from pydantic import BaseModel, Field, validator

class UserRequest(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    email: str
    age: int = Field(..., ge=18, le=150)
    
    @validator('email')
    def email_must_be_valid(cls, v):
        if '@' not in v:
            raise ValueError('Invalid email')
        return v.lower()

Практические советы

  1. Не переусложняй — типизация должна помогать, а не замедлять разработку
  2. Используй Any осторожно — это убивает смысл типизации
  3. Типизируй параметры и return types — внутренние переменные часто можно оставить
  4. Постепенное внедрение — не нужно типизировать весь старый код сразу
  5. Комбинируй с unit тестами — типизация дополняет, а не заменяет тесты

Заключение

Типизация в Python — это не обязательное украшение, а инвестиция в качество кода. Я рекомендую использовать её везде, где это имеет смысл, особенно в больших проектах и командной разработке.