Запись JSON-структур в файловую систему Python
Основные подходы к записи 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')
Файл использует табуляцию вместо пробелов. Можно задать любую строку отступа.