Сохранение и сериализация данных с помощью стандартной библиотеки Python: json, pickle, csv

Для сохранения данных в файл или передачи по сети необходима сериализация. Python предоставляет три стандартных инструмента, каждый из которых отличается характером:

  • json – человеко‑читаемый текстовый формат, отлично подходит для обмена между языками;
  • pickle – бинарный формат, сохраняющий объекты Python «как есть», но с риском безопасности;
  • csv – простейший текстовый формат для табличных данных, широко поддерживаемый.

Форматы доставки данных

  • json: человеко‑читаемый, кросс‑язычный;
  • pickle: бинарный, сохраняет объекты Python полностью, но опасен;
  • csv: простейший текстовый формат для таблиц, универсален.

В этой статье мы разберём, как выбирать между этими модулями в зависимости от того, какие данные и для чего вы хотите сохранить.


1. JSON

1.1 Общая информация

JSON (JavaScript Object Notation) – текстовый и языко‑независимый формат. Он широко используется для конфигурационных файлов, API‑ответов, логов и т.д. В Python работа с JSON осуществляется через модуль json.

1.2 Основные API (часто используемые)

  • json.dump(obj, fp, ...) / json.load(fp, ...) – сохранение/чтение из файла;
  • json.dumps(obj, ...) / json.loads(s, ...) – преобразование в строку/обратное.

Полезные параметры:

  • ensure_ascii=False – сохраняет и выводит символы вне ASCII без экранирования;
  • indent=2 – красивый вывод;
  • default=... – функция‑замена для типов, которые не сериализуются по умолчанию.

1.3 Пример использования (базовый)

import json

data = {
    "name": "Alice",
    "age": 30,
    "skills": ["Python", "Data Science"]
}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded)

1.4 Как обойти ограничения типов в JSON

JSON поддерживает только dict, list, str, int/float, bool, None. Для типов вроде datetime нужно использовать default.

import json
from datetime import datetime, timezone

payload = {"created_at": datetime.now(timezone.utc)}

def to_jsonable(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not JSON serializable: {type(obj)!r}")

s = json.dumps(payload, default=to_jsonable, ensure_ascii=False)
print(s)

1.5 Плюсы и минусы

Плюсы

  • Кросс‑язычный обмен;
  • Читаемость и совместимость с Git;
  • Нет выполнения кода при загрузке.

Минусы

  • Ограниченная выразительность типов (datetime, set, Decimal, бинарные данные);
  • При больших данных может быть медленнее и занимать больше места.

2. Pickle

2.1 Общая информация

pickle – формат, сохраняющий объекты Python «как есть» в бинарном виде. При загрузке почти идентичный объект восстанавливается.

Когда удобно

  • Сохранять сложные объекты Python (классы, вложенные структуры, обученные модели);
  • Не требуется обмен с другими языками.

Когда не стоит

  • При работе с ненадёжными источниками (pickle.load() может выполнить произвольный код);
  • При необходимости совместимости с другими системами.

2.2 Основные API (4 наиболее часто используемых)

  • pickle.dump(obj, file, protocol=...) – объект → файл;
  • pickle.load(file) – файл → объект;
  • pickle.dumps(obj, protocol=...) – объект → bytes;
  • pickle.loads(data) – bytes → объект.
import pickle

data = {"a": [1, 2, 3], "b": ("x", "y")}

with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

with open("data.pkl", "rb") as f:
    loaded = pickle.load(f)

print(loaded)

2.3 Что такое protocol и зачем его задать?

protocol – версия формата pickle. Выбор влияет на размер, скорость и совместимость.

  • По умолчанию используется «наилучший» для текущей версии Python;
  • Если нужна совместимость с более старыми версиями – задайте более низкий протокол;
  • Для оптимизации размера/скорости используйте pickle.HIGHEST_PROTOCOL.
import pickle

with open("data.pkl", "wb") as f:
    pickle.dump({"x": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)

2.4 Важные предостережения

pickle.load() может выполнить код, содержащийся в pickle‑файле. Поэтому:

  • Не загружайте pickle из ненадёжного источника;
  • Для обмена данных используйте текстовые форматы, например json.

2.5 Плюсы и минусы

Плюсы

  • Сохраняет практически любой объект Python;
  • Быстрее и компактнее, чем json для сложных структур.

Минусы

  • Риск безопасности – загрузка из ненадёжного источника опасна;
  • Не совместим с другими языками;
  • При изменении классов старые pickle‑файлы могут перестать работать.

3. CSV

3.1 Общая информация

CSV (Comma-Separated Values) – самый простой формат для табличных данных. Часто используется в таблицах, экспорте/импорте данных и простых логах.

3.2 Основные API (часто используемые)

  • csv.reader, csv.writer – работа со списками;
  • csv.DictReader, csv.DictWriter – работа с словарями (обычно предпочтительнее).

3.3 Пример использования (DictWriter/DictReader)

import csv

data = [
    {"name": "Alice", "age": 30, "city": "Seoul"},
    {"name": "Bob",   "age": 25, "city": "Busan"},
]

with open("people.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(data)

with open("people.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    loaded = list(reader)

print(loaded)

3.4 Три важные нюанса при работе с CSV

  1. newline="" обязательно – особенно в Windows, чтобы избежать двойных переводов строк;
  2. Все данные читаются как строки – необходимо вручную преобразовывать типы;
  3. Разделители, кавычки, переводы строк могут встречаться в данных – используйте модуль csv, а не простое split(',').

3.5 Плюсы и минусы

Плюсы

  • Очень легкий и универсальный формат;
  • Поддерживается большинством инструментов.

Минусы

  • Сложные вложенные структуры трудно представить;
  • Отсутствие типовой информации, требуется ручная конвертация.

4. Сравнение и руководство по выбору

Параметр JSON Pickle CSV
Совместимость Очень хорошая Только Python Очень хорошая
Читаемость Высокая Низкая (бинарный) Высокая
Выразительность типов Ограниченная Очень высокая Ограниченная
Безопасность Относительно безопасна Внимание Относительно безопасна
Структура данных Дерево (вложенные) «Python‑объект как есть» Таблица (строки/столбцы)

Кратко:

  • Обмен с другими системамиjson;
  • Сохранение Python‑объектов целикомpickle (с осторожностью);
  • Экспорт/импорт таблицcsv.

5. Сохранение и восстановление одних данных тремя способами

import json, pickle, csv

data = [
    {"id": 1, "name": "Alice", "score": 95.5},
    {"id": 2, "name": "Bob",   "score": 88.0},
]

# 1) JSON
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    json_loaded = json.load(f)

# 2) Pickle
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

with open("data.pkl", "rb") as f:
    pickle_loaded = pickle.load(f)

# 3) CSV
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["id", "name", "score"])
    writer.writeheader()
    writer.writerows(data)

with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    csv_loaded = [
        {"id": int(row["id"]), "name": row["name"], "score": float(row["score"])}
        for row in reader
    ]

print(json_loaded)
print(pickle_loaded)
print(csv_loaded)

Ключевые моменты

  • В CSV необходимо вручную преобразовывать типы;
  • Pickle удобен, но требует осторожности с источником данных.

6. Итоги

Стандартная библиотека Python покрывает широкий спектр задач по сохранению и сериализации данных.

  • Если данные должны быть читаемыми и совместимыми с другими языками – используйте json;
  • Если нужно сохранить объекты Python целиком – применяйте pickle (с учётом безопасности);
  • Если требуется простое табличное представление – выбирайте csv.

Выбор зависит от формы данных и цели их использования – это делает процесс быстрым и надёжным.