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

Что использовал для сериализации и десериализации данных?

1.0 Junior🔥 31 комментариев
#Брокеры сообщений

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

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

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

Сериализация и десериализация данных: практический опыт

Это один из самых часто используемых инструментов в Python разработке. Расскажу про каждый из инструментов, где я их использовал и почему.

1. JSON (самый распространённый)

Где использовал:

  • REST APIs (FastAPI, Flask)
  • Конфигурационные файлы
  • Логирование и отладка
  • Клиент-серверная коммуникация
import json

# Сериализация
data = {"user_id": 123, "name": "Alice", "active": True}
json_string = json.dumps(data)
print(json_string)  # {"user_id": 123, "name": "Alice", "active": true}

# Десериализация
parsed = json.loads(json_string)
print(parsed["name"])  # Alice

# Файлы
with open("config.json") as f:
    config = json.load(f)

with open("output.json", "w") as f:
    json.dump(data, f, indent=2)

Когда использовать:

  • Веб-APIs (REST)
  • Конфигурационные файлы
  • Логирование
  • Общее использование (везде поддерживается)

Недостатки:

  • Медленнее двоичных форматов
  • Нет поддержки бинарных данных (нужна Base64)
  • Нет типов данных (всё строки/числа/bool)

2. Pickle (Python-специфичный)

Где использовал:

  • Сохранение Python объектов (trained ML модели)
  • Кэширование в памяти
  • Сохранение сложных структур
import pickle

class Model:
    def __init__(self, weights):
        self.weights = weights

model = Model([1, 2, 3])

# Сохранение модели
with open("model.pkl", "wb") as f:
    pickle.dump(model, f)

# Загрузка
with open("model.pkl", "rb") as f:
    loaded_model = pickle.load(f)

print(loaded_model.weights)  # [1, 2, 3]

Когда использовать:

  • Machine Learning (scikit-learn, TensorFlow)
  • Сохранение Python объектов
  • Internal использование (не для передачи между системами)

Важное предупреждение:

# НИКОГДА не десериализуй pickle из неиспользуемого источника!
# Pickle может выполнить произвольный код

# ✗ ОПАСНО
untrusted_data = receive_from_internet()
pickle.loads(untrusted_data)  # Может быть атака!

# ✓ БЕЗОПАСНО
# Используй для своих данных только
my_model = pickle.loads(my_own_saved_model)

3. Pydantic (мой любимый для современных проектов)

Где использовал:

  • Валидация данных в FastAPI
  • Типизированная сериализация
  • API schemas
  • ORM моделями интеграция
from pydantic import BaseModel, EmailStr, Field
from datetime import datetime

class User(BaseModel):
    id: int
    name: str = Field(..., min_length=1)
    email: EmailStr
    age: int = Field(..., ge=0, le=150)
    created_at: datetime

# Десериализация с валидацией
user_data = {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "age": 30,
    "created_at": "2023-01-01T12:00:00"
}

user = User(**user_data)  # Валидирует автоматически
print(user.email)  # alice@example.com

# Сериализация
json_data = user.model_dump_json()
print(json_data)  # {"id": 1, "name": "Alice", ...}

# С исключением полей
partial = user.model_dump(exclude={"id"})
print(partial)  # {"name": "Alice", "email": "alice@example.com", ...}

Использование в FastAPI:

from fastapi import FastAPI

app = FastAPI()

@app.post("/users")
def create_user(user: User):  # Pydantic автоматически парсит и валидирует
    # user уже типизирован и валидирован
    return {"status": "created", "user": user}

# curl -X POST http://localhost:8000/users \
#   -H "Content-Type: application/json" \
#   -d '{"id": 1, "name": "Alice", "email": "alice@example.com", "age": 30, "created_at": "2023-01-01T12:00:00"}'

Преимущества Pydantic:

  • Type hints + валидация
  • Хорошие error messages
  • JSON schema автоматически
  • Быстро (С extensions)
  • Интеграция с FastAPI, SQLAlchemy

4. SQLAlchemy (для ORM)

Где использовал:

  • Работа с базами данных
  • Объектно-реляционное отображение
  • Автоматическая валидация на уровне БД
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base, Session

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    email = Column(String(100), unique=True)

# Сохранение
user = User(name="Alice", email="alice@example.com")
session.add(user)
session.commit()

# Чтение
user = session.query(User).filter(User.email == "alice@example.com").first()

# Обновление
user.name = "Alice Updated"
session.commit()

# Удаление
session.delete(user)
session.commit()

5. MessagePack (для производительности)

Где использовал:

  • Real-time обновления (WebSockets)
  • RPC системы
  • High-frequency data transfer
import msgpack

data = {"user_id": 123, "action": "login", "timestamp": 1234567890}

# Сериализация
packed = msgpack.packb(data)
print(f"Size: {len(packed)} bytes")  # Меньше чем JSON

# Десериализация
data = msgpack.unpackb(packed)
print(data)  # {b'user_id': 123, ...}

6. YAML (для конфигов)

Где использовал:

  • Docker Compose файлы
  • Kubernetes конфигурация
  • Application configs
  • Human-readable конфигурация
import yaml

# YAML конфиг файл
yaml_config = """
database:
  host: localhost
  port: 5432
api:
  timeout: 30
  retries: 3
"""

config = yaml.safe_load(yaml_config)
print(config["database"]["host"])  # localhost

# Сохранение
with open("config.yaml", "w") as f:
    yaml.dump(config, f, default_flow_style=False)

7. CSV (для табличных данных)

Где использовал:

  • Data import/export
  • Отчёты
  • Интеграция с Excel, Google Sheets
import csv
from io import StringIO

# Чтение
with open("data.csv") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["email"])

# Запись
data = [
    {"name": "Alice", "email": "alice@example.com"},
    {"name": "Bob", "email": "bob@example.com"}
]

with open("output.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "email"])
    writer.writeheader()
    writer.writerows(data)

8. Protocol Buffers (для gRPC)

Где использовал:

  • gRPC системы
  • Микросервисная коммуникация
  • Высокопроизводительные системы
// message.proto
syntax = "proto3";

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
}
# Генерируется из .proto файла
from message_pb2 import User

user = User()
user.id = 1
user.name = "Alice"
user.email = "alice@example.com"

# Сериализация
serialized = user.SerializeToString()

# Десериализация
deserialized_user = User()
deserialized_user.ParseFromString(serialized)

Сравнительная таблица

ИнструментUse CaseСкоростьРазмерТипизацияБезопасность
JSONREST APIsСредняяСреднийНетХорошая
PickleML моделиСредняяСреднийДаОПАСНО
PydanticFastAPIБыстроСреднийДа (type hints)Хорошая
SQLAlchemyБДБыстроN/AДаХорошая
MessagePackReal-timeБыстроМаленькийНетХорошая
YAMLКонфигиМедленноБольшийНетХорошая
CSVТаблицыМедленноСреднийНетХорошая
ProtobufgRPCОчень быстроМаленькийДаОчень хорошая

Мой выбор по сценариям

# Веб-API
REST API → JSON + Pydantic ✓

# Микросервисы
Microservices → Protocol Buffers + gRPC ✓

# Real-time данные
WebSockets → MessagePack ✓

# Конфигурация
AppConfig → YAML ✓

# База данных
Database → SQLAlchemy ✓

# Machine Learning
ML Models → Pickle (осторожно!) ✓

# Таблицы/отчёты
CSV export → CSV ✓

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

# Золотой стандарт для современного приложения:

from fastapi import FastAPI
from pydantic import BaseModel
from sqlalchemy.orm import Session

app = FastAPI()

class UserInput(BaseModel):
    name: str
    email: str

@app.post("/users")
def create_user(user_data: UserInput, db: Session):  # Pydantic + SQLAlchemy
    user = UserModel(**user_data.model_dump())
    db.add(user)
    db.commit()
    return user  # FastAPI автоматически сериализует JSON

Вывод

Выбор инструмента зависит от контекста:

  • REST API → JSON + Pydantic
  • Production System → Protocol Buffers или MessagePack
  • Config → YAML
  • Database → SQLAlchemy
  • Reporting → CSV

В большинстве случаев Pydantic + JSON является отличным выбором благодаря простоте, скорости разработки и безопасности.

Что использовал для сериализации и десериализации данных? | PrepBro