Запись JSON-структур в файловую систему Python

Раздел: Обработка данных -> JSON

Основные подходы к записи JSON

Наиболее эффективное решение: использование json.dump() с менеджером контекста

Этот способ объединяет сериализацию и запись в файл в одной операции, автоматически закрывая файл и обеспечивая корректную обработку кодировки. Метод json.dump() записывает объект Python непосредственно в файловый объект.

import json

data = {'name': 'Алиса', 'age': 30, 'city': 'Москва'}

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

Python 3 json (работа с json в python 3)

В результате создаётся файл data.json с отступами (indent=4) и русскими символами без экранирования (ensure_ascii=False). Менеджер контекста (with open) гарантирует закрытие файла даже при возникновении ошибки.

Типичные проблемы и их решения:

  • TypeError: Object of type ... is not JSON serializable – возникает, если в данных есть объекты, не поддерживаемые JSON (например, datetime, set). Решение: использовать параметр default или собственный кодировщик.
  • UnicodeEncodeError – обычно при отсутствии кодировки 'utf-8' в режиме записи. Всегда указывайте encoding='utf-8'.
  • FileNotFoundError – если путь к файлу не существует. Используйте os.makedirs() перед открытием.
  • PermissionError – недостаточно прав на запись. Проверьте разрешения или выберите другую директорию.

Как сохранить JSON в файл, сначала получив строку?

Иногда требуется дополнительно обработать строку JSON перед записью. В этом случае используется json.dumps().

import json

data = {'product': 'Ноутбук', 'price': 75000}
json_str = json.dumps(data, ensure_ascii=False, indent=2)

with open('product.json', 'w', encoding='utf-8') as f:
    f.write(json_str)

Json open python (открытие json файла в python)

Позволяет, например, сжать или зашифровать строку перед записью. Подходит, если нужно записать данные частями или в нестандартное устройство.

Возможные ошибки:

  • Попытка записать в файл в текстовом режиме (по умолчанию) – нормально, но для бинарного режима потребуется json_str.encode('utf-8').
  • Забыть закрыть файл – решается менеджером контекста.

Как сделать компактную запись JSON без пробелов?

Если размер файла критичен (например, для передачи по сети), отступы можно убрать, а разделители сделать минимальными.

import json

data = {'key': 'value', 'number': 42}

with open('compact.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, separators=(',', ':'))

преобразовать json в словарь python (преобразование json в словарь python)

Результат: {'key':'value','number':42}. Параметр separators принимает кортеж (разделитель элементов, разделитель ключ-значение).

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

import json

data = {'z': 1, 'a': 2, 'm': 3}

with open('sorted.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, sort_keys=True, indent=4)

сохранить json python (сохранение json в файл python)

Файл будет содержать ключи в алфавитном порядке: a, m, z. Полезно для сравнения файлов или отладки.

Как обработать несериализуемые объекты (datetime, Decimal) при сохранении?

Через параметр default можно задать функцию преобразования.

import json
from datetime import datetime

def default_converter(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Object of type {type(obj)} is not JSON serializable")

data = {'event': 'Конференция', 'date': datetime(2025, 5, 10)}

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

Python json lib (библиотека json в python)

В результате дата превратится в строку формата ISO 8601. Альтернатива – создать подкласс json.JSONEncoder.

Как записать несколько JSON-объектов в один файл (JSON Lines)?

import json

records = [
    {'id': 1, 'name': 'Объект A'},
    {'id': 2, 'name': 'Объект B'}
]

with open('records.jsonl', 'w', encoding='utf-8') as f:
    for rec in records:
        f.write(json.dumps(rec, ensure_ascii=False) + '\n')

вложенный json python (вложенный json в python)

Каждая строка файла – отдельный JSON-объект. Удобно для потоковой обработки и больших объёмов данных.

Как сохранить JSON с использованием pathlib?

import json
from pathlib import Path

path = Path('output') / 'data.json'
path.parent.mkdir(parents=True, exist_ok=True)
data = {'test': True}

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

Позволяет работать с путями в объектно-ориентированной манере, автоматически создавать каталоги.

Расширенные примеры сохранения JSON

Пример 1: Сохранение с кастомным JSONEncoder для множеств и дат

Пример
import json
from datetime import date
from decimal import Decimal

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, set):
            return list(obj)
        if isinstance(obj, date):
            return obj.isoformat()
        if isinstance(obj, Decimal):
            return float(obj)
        return super().default(obj)

data = {
    'tags': {'python', 'json', 'example'},
    'price': Decimal('19.99'),
    'created': date(2025, 1, 15)
}

with open('custom.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, cls=CustomEncoder, indent=4, ensure_ascii=False)
Файл custom.json:
{
    "tags": ["json", "example", "python"],
    "price": 19.99,
    "created": "2025-01-15"
}

Пример 2: Сохранение большого объёма данных с итерацией (экономия памяти)

Пример
import json

def large_data_generator(n):
    for i in range(n):
        yield {'index': i, 'value': i * 2}

with open('large.jsonl', 'w', encoding='utf-8') as f:
    for item in large_data_generator(1000):
        f.write(json.dumps(item) + '\n')
Файл large.jsonl содержит 1000 строк, каждая – JSON-объект.

Пример 3: Сохранение JSON в сжатый gzip-файл

Пример
import json
import gzip

data = [{'id': i, 'text': 'строка ' + str(i)} for i in range(100)]

with gzip.open('compressed.json.gz', 'wt', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
Создан файл compressed.json.gz, который занимает меньше места на диске.

Пример 4: Запись JSON с проверкой целостности через контрольную сумму

Пример
import json
import hashlib

data = {'payload': 'секретные данные'}

# Сериализация и расчёт хеша
json_str = json.dumps(data, ensure_ascii=False, sort_keys=True)
hash_value = hashlib.sha256(json_str.encode('utf-8')).hexdigest()

# Сохранение с хешем
with open('verified.json', 'w', encoding='utf-8') as f:
    json.dump({'data': data, 'hash': hash_value}, f, ensure_ascii=False, indent=2)
Файл verified.json содержит данные и их хеш, что позволяет при загрузке проверить неизменность.

Пример 5: Параллельная запись нескольких JSON-файлов (concurrent.futures)

Пример
import json
import concurrent.futures
import os

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

os.makedirs('parallel_output', exist_ok=True)
datasets = {
    'file1.json': {'a': 1},
    'file2.json': {'b': 2},
    'file3.json': {'c': 3}
}

with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [executor.submit(save_json, os.path.join('parallel_output', fname), data)
               for fname, data in datasets.items()]
    concurrent.futures.wait(futures)
Создаётся каталог parallel_output с тремя JSON-файлами.

Пример 6: Сохранение JSON с нестандартными отступами и управлением пробелами

Пример
import json

data = {
    'level1': {
        'level2': {
            'field': 'value'
        }
    }
}

with open('custom_spacing.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent='\t')
Файл использует табуляцию вместо пробелов. Можно задать любую строку отступа.

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

En
сохранить json python (python)