
JSON и CSV в Python: чтение, запись и проверка данных
Разбираемся, чем JSON отличается от CSV, читаем и записываем оба формата стандартной библиотекой Python и проверяем структуру до обработки.
Содержание
Настройки программы удобно хранить как вложенный документ, а отчёт из одинаковых строк — как таблицу. Поэтому один скрипт может читать параметры из JSON и выгружать результат в CSV. Форматы решают разные задачи, хотя оба выглядят как обычный текстовый файл.
JSON хранит значения с именами, списки и вложенные объекты. CSV хранит таблицу: первая строка обычно содержит названия столбцов, остальные — записи. Прежде чем писать обработчик, определите структуру данных: какие поля обязательны, какого они типа и что делать с неизвестным значением.
В этом уроке все файлы создаются в локальном каталоге data. Работа с каталогами опирается на предыдущий материал о pathlib, а ожидаемые ошибки разбираются по правилам из урока об исключениях.
Сохраните настройки в JSON
Создайте файл data_demo.py в пустом учебном каталоге. Первый фрагмент создаёт подкаталог data и полностью записывает файл settings.json:
import json
from pathlib import Path
data_dir = Path(__file__).resolve().parent / "data"
data_dir.mkdir(exist_ok=True)
settings_path = data_dir / "settings.json"
settings = {
"project": "Проверка сайтов",
"timeout": 5,
"targets": ["https://example.com", "https://example.org"],
}
with settings_path.open("w", encoding="utf-8") as file:
json.dump(settings, file, ensure_ascii=False, indent=2)
print(f"Настройки записаны: {settings_path}")
Запустите python data_demo.py из учебного каталога. json.dump получает объект Python и открытый файл. Параметр ensure_ascii=False оставляет русские буквы читаемыми, а indent=2 добавляет отступы. Без отступов документ был бы компактнее, но его сложнее проверять вручную.
Запись с режимом "w" заменяет прежнее содержимое. Не направляйте пример на важный файл. Для рабочих настроек сначала пишут временный файл, проверяют его и только затем заменяют оригинал.
Прочитайте JSON и проверьте ожидаемые поля
Добавьте ниже код чтения. json.load преобразует объект JSON в словарь Python, но не знает, какие поля нужны вашей программе:
with settings_path.open("r", encoding="utf-8") as file:
loaded = json.load(file)
if not isinstance(loaded, dict):
raise ValueError("В корне settings.json должен быть объект")
project = loaded.get("project")
timeout = loaded.get("timeout")
targets = loaded.get("targets")
if not isinstance(project, str) or not project.strip():
raise ValueError("Поле project должно быть непустой строкой")
if not isinstance(timeout, int) or timeout <= 0:
raise ValueError("Поле timeout должно быть целым числом больше нуля")
if not isinstance(targets, list) or not all(isinstance(item, str) for item in targets):
raise ValueError("Поле targets должно быть списком строк")
print(f"Проект: {project}; адресов: {len(targets)}")
После запуска ожидается строка Проект: Проверка сайтов; адресов: 2. Проверки отделяют корректный синтаксис от пригодных данных. Документ {"timeout": "быстро"} является корректным JSON, но не подходит программе, которая ждёт количество секунд.
Если файл повреждён, json.load вызывает json.JSONDecodeError; если его нет — FileNotFoundError. Перехватывайте эти исключения там, где можно сообщить пользователю имя файла и понятное действие, а не продолжать с выдуманными значениями.
Запишите плоский отчёт в CSV
Теперь представим результат двумя строками. Добавьте импорт csv в начало файла, а следующий фрагмент — после проверки настроек:
import csv
rows = [
{"url": targets[0], "status": 200, "elapsed_ms": 184},
{"url": targets[1], "status": 503, "elapsed_ms": 912},
]
report_path = data_dir / "report.csv"
fieldnames = ["url", "status", "elapsed_ms"]
with report_path.open("w", encoding="utf-8", newline="") as file:
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
print(f"Отчёт записан: {report_path}")
DictWriter сопоставляет ключи словаря со столбцами из fieldnames. Вызов writeheader() записывает заголовок, а writerows() — строки. Параметр newline="" передаёт управление переводами строк модулю csv; это предотвращает лишние пустые строки на некоторых системах.
В примере коды ответа заданы вручную и не являются результатом реальной проверки сайтов. После запуска откройте data/report.csv: в нём должны быть заголовок и две строки. Если файл уже существовал, он будет заменён.
Преобразуйте значения после чтения CSV
CSV не хранит тип int. Даже ячейка 200 при обычном чтении становится строкой "200". Следующий фрагмент читает созданный отчёт и преобразует два столбца явно:
with report_path.open("r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for line_number, row in enumerate(reader, start=2):
try:
status = int(row["status"])
elapsed_ms = int(row["elapsed_ms"])
except (KeyError, TypeError, ValueError) as error:
raise ValueError(
f"Некорректная строка {line_number} в {report_path}"
) from error
print(row["url"], status, elapsed_ms)
Нумерация начинается с двух, потому что первая строка занята заголовком. KeyError означает отсутствие столбца, а ValueError — невозможность превратить значение в целое число. Так сообщение указывает на конкретную строку входного файла.
У CSV нет единственного варианта разделителя. Русскоязычный табличный редактор иногда сохраняет файл с точкой с запятой. В таком случае задайте delimiter=";" и при чтении, и при записи. Не угадывайте формат по одному примеру: зафиксируйте его в описании импорта или получите от источника.
Выберите формат по структуре, а не по привычке
Используйте JSON для конфигурации, ответа API или документа с вложенными списками. CSV удобен для экспорта плоских записей, потоковой обработки больших таблиц и обмена с табличным редактором. Если в одной ячейке CSV начинает появляться JSON, вероятно, структура уже не является простой таблицей.
Не загружайте без ограничения огромный JSON из недоверенного источника: разбор документа расходует память и процессорное время. Перед обработкой внешнего файла полезно ограничить допустимый размер, число строк и длину отдельных значений.
Официальные справочники описывают json и csv. Следующий урок превратит учебный файл в нормальную консольную программу с аргументами командной строки.
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Когда выбирать JSON, а когда CSV?
JSON удобен для вложенных настроек и обмена данными между программами. CSV подходит для плоской таблицы, которую нужно открыть в табличном редакторе или обработать построчно.
Почему CSV нужно открывать с newline=''?
Так модуль csv сам управляет переводами строк. Без этого на некоторых системах при записи могут появиться лишние пустые строки.
Проверяет ли json.load структуру документа?
Он проверяет синтаксис JSON, но не наличие нужных полей и их типы. Эти условия программа проверяет отдельно после чтения.


