📐 Typing: TypedDict, Literal, Annotated в реальных проектах
Аннотации типов в Python — это не только int и str. Для сложных сценариев есть мощные инструменты: TypedDict, Literal, Annotated. Они помогают писать код понятнее и ловить ошибки ещё на этапе разработки.
📦 TypedDict — словари со строгой схемой
from typing import TypedDict
class User(TypedDict):
id: int
name: str
is_admin: bool
u: User = {"id": 1, "name": "Иван", "is_admin": False}
➡️ Теперь IDE и mypy знают структуру словаря. Ошибку в ключе или типе отловишь сразу.
🎯 Literal — фиксированные значения
from typing import Literal
def set_status(status: Literal["NEW", "IN_PROGRESS", "DONE"]) -> None:
print(f"Статус: {status}")
set_status("NEW") # ✅
set_status("INVALID") # ❌ mypy отловит
➡️ Полезно, когда параметр должен принимать строго ограниченные значения.
🧩 Annotated — тип + метаданные
from typing import Annotated
from dataclasses import dataclass
@dataclass
class User:
id: Annotated[int, "DB Primary Key"]
email: Annotated[str, "must be valid email"]
➡️ Аннотации становятся документацией и могут использоваться библиотеками (например, валидацией в FastAPI).
⚡️ TypedDict с опциональными ключами
class Config(TypedDict, total=False):
debug: bool
log_level: str
cfg: Config = {"debug": True} # ok
➡️ total=False позволяет делать часть ключей необязательными.
🔄 Literal в связке с Enum
from typing import Literal
Role = Literal["user", "admin", "moderator"]
def check_role(role: Role): ...
➡️ Даёт компактную альтернативу Enum, если не нужно хранить методы.
📑 Annotated для валидации данных
В FastAPI:
from typing import Annotated
from fastapi import Query
def read_items(size: Annotated[int, Query(ge=1, le=100)]):
return {"size": size}
➡️Ограничения накладываются прямо через типы, без лишнего кода.
🧠 Совмещение инструментов
class Product(TypedDict):
id: int
status: Literal["active", "archived"]
def process(p: Product): ...
➡️ Получается словарь со строгой схемой и фиксированным набором значений.
🗣️ Запомни: TypedDict даёт строгие словари, Literal ограничивает набор значений, Annotated связывает тип с метаданными. Вместе они делают код самодокументируемым и надёжным.
Аннотации типов в Python — это не только int и str. Для сложных сценариев есть мощные инструменты: TypedDict, Literal, Annotated. Они помогают писать код понятнее и ловить ошибки ещё на этапе разработки.
📦 TypedDict — словари со строгой схемой
from typing import TypedDict
class User(TypedDict):
id: int
name: str
is_admin: bool
u: User = {"id": 1, "name": "Иван", "is_admin": False}
➡️ Теперь IDE и mypy знают структуру словаря. Ошибку в ключе или типе отловишь сразу.
🎯 Literal — фиксированные значения
from typing import Literal
def set_status(status: Literal["NEW", "IN_PROGRESS", "DONE"]) -> None:
print(f"Статус: {status}")
set_status("NEW") # ✅
set_status("INVALID") # ❌ mypy отловит
➡️ Полезно, когда параметр должен принимать строго ограниченные значения.
🧩 Annotated — тип + метаданные
from typing import Annotated
from dataclasses import dataclass
@dataclass
class User:
id: Annotated[int, "DB Primary Key"]
email: Annotated[str, "must be valid email"]
➡️ Аннотации становятся документацией и могут использоваться библиотеками (например, валидацией в FastAPI).
⚡️ TypedDict с опциональными ключами
class Config(TypedDict, total=False):
debug: bool
log_level: str
cfg: Config = {"debug": True} # ok
➡️ total=False позволяет делать часть ключей необязательными.
🔄 Literal в связке с Enum
from typing import Literal
Role = Literal["user", "admin", "moderator"]
def check_role(role: Role): ...
➡️ Даёт компактную альтернативу Enum, если не нужно хранить методы.
📑 Annotated для валидации данных
В FastAPI:
from typing import Annotated
from fastapi import Query
def read_items(size: Annotated[int, Query(ge=1, le=100)]):
return {"size": size}
➡️Ограничения накладываются прямо через типы, без лишнего кода.
🧠 Совмещение инструментов
class Product(TypedDict):
id: int
status: Literal["active", "archived"]
def process(p: Product): ...
➡️ Получается словарь со строгой схемой и фиксированным набором значений.
🗣️ Запомни: TypedDict даёт строгие словари, Literal ограничивает набор значений, Annotated связывает тип с метаданными. Вместе они делают код самодокументируемым и надёжным.