Чтение и запись JSON в Python

Почему JSON полезен
JSON (JavaScript Object Notation) — текстовый формат обмена данными. Он удобен тем, что:
- легко читается человеком;
- поддерживается почти во всех языках программирования;
- подходит для сериализации простых структур: словарей (objects), списков (arrays), чисел, строк и булевых значений.
Краткое определение: сериализация — преобразование объекта в строку или файл; десериализация — обратное преобразование.
Базовые операции: запись в файл
Чтобы сохранить словарь или список в файл JSON, используйте модуль json. Обратите внимание на кодировку и параметры удобочитаемости (indent) и сохранения символов Unicode (ensure_ascii).
Пример: запись словаря в файл myfile.json
import json
data = {"MUO": "Media", "Google": "Search", "Python": "Language"}
with open("myfile.json", "w", encoding="utf-8") as j:
json.dump(data, j, ensure_ascii=False, indent=4)Запись более сложной структуры (вложенный список/словарь):
import json
data = {"Sites": [{"MUO": "Media", "Google": "Search", "Python": "Language"}]}
with open("myfile.json", "w", encoding="utf-8") as j:
json.dump(data, j, ensure_ascii=False, indent=2)Важно: используйте encoding=”utf-8” для корректной записи нелатинских символов и ensure_ascii=False, чтобы не экранировать юникод.
Как сохранить список как JSON
Прямо список тоже можно записать, но часто удобнее привести данные к словарю, если у вас пары ключ/значение.
Преобразование списка в словарь по парам и запись:
import json
data = ["MUO", "Media", "Google", "Search", "Python", "Language"]
# Преобразуем в словарь: каждая пара элементов — ключ и значение
data = {data[i]: data[i+1] for i in range(0, len(data), 2)}
with open("myfile.json", "w", encoding="utf-8") as j:
json.dump(data, j, ensure_ascii=False, indent=4)Слияние двух списков в словарь перед сохранением:
import json
data_keys = ["MUO", "Google", "Python"]
data_values = ["Media", "Search", "Language"]
outputData = {data_keys[i]: data_values[i] for i in range(len(data_keys))}
with open("myfile.json", "w", encoding="utf-8") as j:
json.dump(outputData, j, ensure_ascii=False, indent=4)Чтение и доступ к данным
Чтение всего объекта из файла — json.load. Для строк используйте json.loads.
import json
with open("test.json", "r", encoding="utf-8") as j:
mydata = json.load(j)
print(mydata)
# Ожидаемый вывод: {'MUO': 'Media', 'Google': 'Search', 'Python': 'Language'}Доступ к конкретному полю:
with open("test.json", "r", encoding="utf-8") as j:
mydata = json.load(j)
print(mydata["MUO"]) # Выведет: MediaПолезные параметры и советы
- indent — делает JSON удобочитаемым; используйте число пробелов (обычно 2 или 4).
- ensure_ascii=False — сохраняет символы Unicode без экранирования.
- sort_keys=True — упорядочивает ключи в выводе, удобно для diff’ов.
- json.dumps возвращает строку, json.dump записывает в файл.
- Для произвольных объектов (например, datetime) используйте параметр default или вручную преобразуйте в сериализуемый тип.
Пример сериализации нестандартного объекта:
import json
from datetime import datetime
class Event:
def __init__(self, name, date):
self.name = name
self.date = date
def to_dict(self):
return {"name": self.name, "date": self.date.isoformat()}
event = Event("Launch", datetime.utcnow())
with open("event.json", "w", encoding="utf-8") as f:
json.dump(event.to_dict(), f, ensure_ascii=False, indent=2)Когда JSON не подходит или даёт проблемы
- Если нужно сохранять произвольные объекты Python со связями, лучше использовать базу данных или сериализацию pickle (но pickle небезопасен для чтения от третьих лиц).
- Для больших двоичных данных (изображения, файлы) храните ссылку/путь, а не сам байтовый контент в JSON.
- JSON не сохраняет типы Python (например, tuple станет массивом, set нельзя сериализовать напрямую).
Альтернативы и подходы
- YAML — человекочитаемый и поддерживает ссылки, но сложнее парсить в некоторых языках.
- MessagePack — бинарный формат, компактнее и быстрее при передаче.
- BSON — использует MongoDB и подходит для более сложных типов.
- NoSQL БД (CouchDB, MongoDB) позволяют хранить документы JSON напрямую.
Критерии приёмки
- Файлы JSON корректно парсятся модулем json без ошибок.
- Кодировка UTF‑8 сохранена; символы не экранируются ненужно.
- Структура данных соответствует контракту API (ключи и типы значений).
- Тесты покрывают чтение/запись и обработку невалидных данных.
Тесты и сценарии проверки
- Запись и последующее чтение возвращают эквивалентную структуру.
- Попытка сериализовать несериализуемый объект — ожидание TypeError или корректная обработка через default.
- Файл с Unicode символами читается и содержит ожидаемые символы.
- Поведение при частично повреждённом JSON: json.load вызывает JSONDecodeError.
Чек‑лист ролей
Разработчик:
- Использует encoding=”utf-8” и ensure_ascii=False при записи.
- Обрабатывает исключения (IOError, JSONDecodeError).
- Добавляет тесты для граничных случаев.
Рецензент кода:
- Проверяет корректность структуры JSON и использование indent/sort_keys для читаемости.
- Убедится, что чувствительные данные не пишутся в открытые файлы.
Операции/DevOps:
- Настраивает резервное копирование JSON‑файлов и права доступа.
- Валидирует JSON при загрузке в продакшен.
Краткий глоссарий
- JSON — текстовый формат обмена данными.
- Сериализация — перевод объекта в формат для хранения или передачи.
- Десериализация — восстановление объекта из формата.
- NoSQL — класс баз данных, часто хранящих документы JSON.
Итог
JSON — простой и универсальный способ обмена данными между сервисами и компонентами. В Python это встроено и легко использовать, но важно следовать практикам по кодировке, обработке ошибок и тестированию. Для сложных или бинарных данных рассматривайте альтернативы.
Важно: всегда валидируйте входные данные и не доверяйте содержимому JSON из ненадёжных источников.
Похожие материалы
Gmail как приложение для рабочего стола
Как сохранить Mac прохладным в жару
Astro + Nano Stores: управление состоянием
Отключить «Не беспокоить» в Google Maps при вождении
SSH-ключи: создать и установить на сервер