Как сохранить словарь в файл на Python: обзор методов и примеры кода

Раздел: Ввод-вывод -> Файловый ввод-вывод

Сохранение словарей в файлы: основные подходы

Использование модуля json (рекомендуемый способ)

Как сохранить словарь в читаемом формате, который легко загрузить обратно и использовать в других языках?

Модуль json позволяет сериализовать словарь в текст, удобный для чтения человеком. Этот метод подходит, если словарь содержит только базовые типы (строки, числа, списки, словари, булевы значения, None).


import json

data = {"name": "Анна", "age": 30, "city": "Москва", "skills": ["Python", "SQL"]}

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

ввод программ на python (ввод данных в программе python)

Параметр ensure_ascii=False сохраняет кириллицу без экранирования, indent=4 добавляет отступы для читаемости.

Проблема: Если в словаре есть объекты вроде datetime, возникнет ошибка TypeError: Object of type datetime is not JSON serializable.

Решение: Использовать параметр default в json.dump() для преобразования сложных типов, например:


def json_serial(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Type {type(obj)} not serializable")

json.dump(data, f, default=json_serial)
        

Python file io (ввод-вывод файлов в python)

1. Сохранение с помощью pickle (для любых объектов Python)

Как сохранить словарь, содержащий произвольные объекты (например, функции, классы, сеты)?

Модуль pickle сериализует практически любой объект Python в бинарный формат. Недостаток - файлы не читаются человеком и могут быть несовместимы между версиями Python.


import pickle

data = {"numbers": {1, 2, 3}, "func": lambda x: x*2}   # set и лямбда

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

Python temp files (временные файлы в python)

Проблема: При загрузке pickle-файла может возникнуть ошибка UnpicklingError, если файл повреждён или создан другой версией Python.

Решение: Всегда проверять версию pickle (protocol), использовать pickle.HIGHEST_PROTOCOL и обрабатывать исключения.

2. Запись через repr() и eval() (простейший / быстрый способ)

Как быстро сохранить словарь без внешних модулей, имея в виду только безопасное окружение?

Метод подходит для отладки или простых скриптов, где словарь гарантированно состоит из типов, представимых литералами (int, str, list, dict, tuple). Нельзя использовать для пользовательских данных из соображений безопасности (eval).


with open("data.txt", "w", encoding="utf-8") as f:
    f.write(repr(data))
    

Python index files (индексация файлов в python)

Загрузка:


with open("data.txt", "r") as f:
    restored = eval(f.read())
    

File python class (класс для работы с файлами в python)

Проблема: eval() может выполнить произвольный код. Никогда не используйте этот способ, если файл мог быть изменён злоумышленником.

3. Сохранение в CSV (для плоских словарей)

Как сохранить словарь с одноуровневыми ключами и простыми значениями в табличный формат?

Модуль csv подходит, если словарь имеет плоскую структуру (ключи - строки, значения - строки или числа). Каждая строка - одна запись.


import csv

data = {"name": "Иван", "age": 25, "city": "СПб"}
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=data.keys())
    writer.writeheader()
    writer.writerow(data)
    

Python file utf 8 (кодировка utf-8 для файлов в python)

Проблема: Вложенные словари или списки не могут быть сохранены напрямую. Придётся предварительно преобразовывать.

4. Использование YAML (гибкий формат с поддержкой комментариев)

Как сохранить словарь с произвольной структурой в формате, удобном для конфигурационных файлов?

YAML - человекочитаемый формат, поддерживающий многие типы данных. Необходимо установить библиотеку pyyaml.


import yaml

data = {"server": {"host": "localhost", "port": 8080}, "debug": True}
with open("config.yaml", "w", encoding="utf-8") as f:
    yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
    

Python config files (конфигурационные файлы в python)

Проблема: Некорректное отображение сложных объектов (например, кортежей - в YAML они превращаются в списки).

5. Модуль shelve (словарь, сохраняемый на диск)

Как получить постоянное хранилище с доступом как к обычному словарю?

shelve использует dbm и pickle под капотом. Позволяет записывать и читать объекты по ключу, не загружая весь словарь в память.


import shelve

data = {"key1": [1,2,3], "key2": {"sub": "value"}}
with shelve.open("mydata.shelve") as db:
    for k, v in data.items():
        db[k] = v
    

Проблема: Ключи должны быть строками. Не все типы значений поддерживаются (ограничения pickle).

- Python file methods (методы работы с файлами в python)
- File models in python (модели файлов в python)
- File handle python (обработка файлов в python)

Расширенные примеры сохранения словарей

Пример 1. Сохранение словаря с датами и множествами через json с кастомным сериализатором

Пример

import json
from datetime import datetime, date
from decimal import Decimal

def custom_serializer(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    if isinstance(obj, Decimal):
        return float(obj)
    if isinstance(obj, set):
        return list(obj)
    raise TypeError(f"Невозможно сериализовать {type(obj)}")

data = {
    "timestamp": datetime.now(),
    "price": Decimal("19.99"),
    "tags": {"python", "json", "example"}
}

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

# Проверка содержимого
with open("advanced.json", "r", encoding="utf-8") as f:
    print(f.read())
{
  "timestamp": "2025-04-14T12:34:56.789012",
  "price": 19.99,
  "tags": ["python", "json", "example"]
}

Пример 2. Сохранение большого словаря по частям (генератор)

Пример

import json

def chunked_dict(items, chunk_size=1000):
    """Генератор, возвращающий фрагменты словаря."""
    partial = {}
    for idx, (k, v) in enumerate(items):
        partial[k] = v
        if (idx + 1) % chunk_size == 0:
            yield partial
            partial = {}
    if partial:
        yield partial

big_dict = {f"key_{i}": i for i in range(5000)}

with open("big_dict.json", "w", encoding="utf-8") as f:
    f.write("[")
    first = True
    for chunk in chunked_dict(big_dict.items()):
        if not first:
            f.write(",\n")
        json.dump(chunk, f, ensure_ascii=False, indent=2)
        first = False
    f.write("]")

# Результат - JSON массив из нескольких объектов

Пример 3. Сохранение в формат msgpack (бинарный компактный формат)

Пример

# pip install msgpack
import msgpack

data = {"key": [1, 2, 3], "nested": {"a": "test"}}

with open("data.msgpack", "wb") as f:
    packed = msgpack.packb(data, use_bin_type=True)
    f.write(packed)

# Чтение
with open("data.msgpack", "rb") as f:
    loaded = msgpack.unpackb(f.read(), raw=False)
    print(loaded)
{'key': [1, 2, 3], 'nested': {'a': 'test'}}

Пример 4. Сохранение с использованием h5py (для научных данных)

Пример

# pip install h5py
import h5py
import numpy as np

data = {
    "metadata": "experiment",
    "values": np.array([1.5, 2.3, 4.1]),
    "sub": {"nested_int": 42}
}

with h5py.File("data.hdf5", "w") as f:
    f.attrs.update(data["metadata"])  # атрибуты для метаданных
    f.create_dataset("values", data=data["values"])
    grp = f.create_group("sub")
    grp.attrs["nested_int"] = data["sub"]["nested_int"]

Пример 5. Сохранение словаря с ключами-числами (json требует строки)

Пример

import json

data = {1: "one", 2: "two", 3: "three"}
# JSON допускает только строковые ключи, поэтому преобразуем
with open("numeric_keys.json", "w") as f:
    # Используем ключи как строки, а при загрузке преобразуем обратно
    json.dump({str(k): v for k, v in data.items()}, f)

# Загрузка с обратным преобразованием
with open("numeric_keys.json", "r") as f:
    loaded = json.load(f)
    restored = {int(k): v for k, v in loaded.items()}
    print(restored)
{1: 'one', 2: 'two', 3: 'three'}

Пример 6. Асинхронное сохранение с помощью aiofiles (для асинхронных приложений)

Пример

import aiofiles
import json
import asyncio

data = {"async": True, "value": 100}

async def save_dict_async():
    async with aiofiles.open("async_data.json", "w", encoding="utf-8") as f:
        await f.write(json.dumps(data, indent=2, ensure_ascii=False))

asyncio.run(save_dict_async())

Сохранение словаря в файл в Python - comments

En
Python сохранить словарь (python)