Работа с JSON: json.dump(), json.load()

Работа с JSON: json.dump(), json.load() Работа с файлами

Привет! Ты уже умеешь работать с CSV и текстовыми файлами. Но есть формат, который стал стандартом для обмена данными в вебе — JSON (JavaScript Object Notation). Он лёгкий, читаемый и идеально подходит для хранения структурированных данных.

В этой статье мы разберём:

  • Что такое JSON и зачем он нужен
  • Как записать JSON в файл: json.dump()
  • Как прочитать JSON из файла: json.load()
  • Как преобразовать JSON в строку: json.dumps()
  • Как разобрать JSON-строку: json.loads()
  • Параметры настройки (indent, ensure_ascii, sort_keys)

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Python (модуль json встроенный — ничего не нужно устанавливать!)
  • Базовое понимание словарей и списков
  • Желание научиться работать с JSON

Совет: JSON — главный формат для обмена данными в REST API. Если ты планируешь работать с веб-разработкой — это обязательно нужно знать!

Основная часть

Что такое JSON?

JSON (JavaScript Object Notation) — это текстовый формат для хранения и передачи структурированных данных. Он основан на синтаксисе JavaScript, но используется во многих языках программирования.

Пример JSON:

{
    "name": "Анна",
    "age": 25,
    "city": "Москва",
    "hobbies": ["чтение", "спорт"],
    "is_active": true,
    "address": {
        "street": "Тверская",
        "house": 10
    }
}

Совет: JSON похож на Python-словарь, но с важными отличиями: ключи должны быть в двойных кавычках, а значения — true/false/null (с маленькой буквы).

Основные функции модуля json

ФункцияЧто делаетКуда
json.dump(obj, file)Записывает JSON в файлВ файл
json.load(file)Читает JSON из файлаИз файла
json.dumps(obj)Преобразует объект в JSON-строкуВ строку
json.loads(str)Преобразует JSON-строку в объектИз строки

Совет: Запомни правило: dump — в файл (вниз), load — из файла (вверх). Буква ‘s’ в конце означает строку (string).

Сохранение JSON в файл: json.dump()

import json

# Данные для сохранения
data = {
    "name": "Анна",
    "age": 25,
    "city": "Москва",
    "hobbies": ["чтение", "спорт"],
    "is_active": True
}

# Записываем в файл
with open('user.json', 'w', encoding='utf-8') as file:
    json.dump(data, file)

print("Данные сохранены в user.json")

Совет: Всегда указывай encoding='utf-8' для корректной работы с русским текстом.

Чтение JSON из файла: json.load()

import json

# Читаем из файла
with open('user.json', 'r', encoding='utf-8') as file:
    data = json.load(file)

print(data)
print(f"Имя: {data['name']}")
print(f"Возраст: {data['age']}")
print(f"Хобби: {', '.join(data['hobbies'])}")

Результат:

{'name': 'Анна', 'age': 25, 'city': 'Москва', 'hobbies': ['чтение', 'спорт'], 'is_active': True}
Имя: Анна
Возраст: 25
Хобби: чтение, спорт

Преобразование в JSON-строку: json.dumps()

import json

data = {
    "name": "Анна",
    "age": 25,
    "city": "Москва"
}

# Преобразуем в строку
json_string = json.dumps(data)
print(type(json_string))  # <class 'str'>
print(json_string)

Результат:

<class 'str'>
{"name": "\u0410\u043d\u043d\u0430", "age": 25, "city": "\u041c\u043e\u0441\u043a\u0432\u0430"}

Совет: По умолчанию русские символы кодируются в Unicode. Чтобы этого избежать, используй параметр ensure_ascii=False.

Парсинг JSON-строки: json.loads()

import json

# JSON-строка
json_string = '{"name": "Анна", "age": 25, "city": "Москва"}'

# Преобразуем в объект Python
data = json.loads(json_string)
print(type(data))  # <class 'dict'>
print(data['name'])  # Анна

Параметры настройки

Форматирование: indent

import json

data = {
    "name": "Анна",
    "age": 25,
    "city": "Москва",
    "hobbies": ["чтение", "спорт"]
}

# С отступами (красиво)
with open('user_pretty.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, indent=4, ensure_ascii=False)

print("Сохранено с форматированием")

Результат в файле:

{
    "name": "Анна",
    "age": 25,
    "city": "Москва",
    "hobbies": [
        "чтение",
        "спорт"
    ]
}

Сортировка ключей: sort_keys

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

Результат (ключи отсортированы по алфавиту):

{
    "age": 25,
    "city": "Москва",
    "hobbies": [
        "чтение",
        "спорт"
    ],
    "name": "Анна"
}

Работа с Unicode: ensure_ascii

# Без ensure_ascii=False — русский текст в Unicode
json_string = json.dumps(data)
print(json_string)  # {"name": "\u0410\u043d\u043d\u0430", ...}

# С ensure_ascii=False — читаемый русский текст
json_string = json.dumps(data, ensure_ascii=False)
print(json_string)  # {"name": "Анна", "age": 25, "city": "Москва"}

Совет: Для работы с русским текстом всегда используй ensure_ascii=False.

Сериализация пользовательских объектов

По умолчанию json не умеет работать с пользовательскими классами. Нужно написать кастомный энкодер.

import json
from datetime import datetime

class User:
    def __init__(self, name, age, created_at):
        self.name = name
        self.age = age
        self.created_at = created_at

# Кастомный энкодер
def custom_encoder(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    if isinstance(obj, User):
        return {
            "name": obj.name,
            "age": obj.age,
            "created_at": obj.created_at.isoformat()
        }
    raise TypeError(f"Object of type {type(obj)} is not JSON serializable")

# Создаём объект
user = User("Анна", 25, datetime.now())

# Сериализуем
json_string = json.dumps(user, default=custom_encoder, ensure_ascii=False, indent=2)
print(json_string)

Совет: Для классов с большим количеством полей удобнее использовать библиотеку dataclasses или pydantic.

Практический пример: сохранение настроек

import json

# Настройки по умолчанию
default_settings = {
    "theme": "light",
    "language": "ru",
    "notifications": True,
    "auto_save": False,
    "font_size": 14
}

def save_settings(settings, filename='settings.json'):
    with open(filename, 'w', encoding='utf-8') as file:
        json.dump(settings, file, indent=4, ensure_ascii=False)
    print(f"Настройки сохранены в {filename}")

def load_settings(filename='settings.json'):
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            return json.load(file)
    except FileNotFoundError:
        print(f"Файл {filename} не найден. Использую настройки по умолчанию.")
        return default_settings

# Сохраняем настройки
user_settings = default_settings.copy()
user_settings['theme'] = 'dark'
user_settings['font_size'] = 16
save_settings(user_settings)

# Загружаем настройки
loaded = load_settings()
print("Загруженные настройки:")
for key, value in loaded.items():
    print(f"  {key}: {value}")

Работа с JSON из API

import json
import requests

# Отправляем запрос к API
response = requests.get('https://api.github.com/users/octocat')

# Получаем JSON-ответ
data = response.json()  # Это эквивалентно json.loads(response.text)

print(f"Имя пользователя: {data['login']}")
print(f"Репозиториев: {data['public_repos']}")
print(f"Подписчиков: {data['followers']}")

Задачи для закрепления

Задача 1. Сохрани словарь {'name': 'Иван', 'age': 30, 'city': 'Москва'} в JSON-файл.

Задача 2. Прочитай JSON-файл из задачи 1 и выведи значения всех ключей.

Задача 3. Преобразуй словарь {'a': 1, 'b': 2, 'c': 3} в JSON-строку.

Задача 4. Разбери JSON-строку '{"name": "Мария", "age": 22}' в словарь.

Задача 5. Сохрани словарь в JSON с отступами 4 пробела и сортировкой ключей.

Ответы:

Задача 1.

import json

data = {'name': 'Иван', 'age': 30, 'city': 'Москва'}
with open('data.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False)

Задача 2.

with open('data.json', 'r', encoding='utf-8') as file:
    data = json.load(file)
    for key, value in data.items():
        print(f"{key}: {value}")

Задача 3.

json_string = json.dumps({'a': 1, 'b': 2, 'c': 3})
print(json_string)

Задача 4.

data = json.loads('{"name": "Мария", "age": 22}')
print(data['name'])  # Мария

Задача 5.

data = {'c': 3, 'a': 1, 'b': 2}
with open('sorted.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, indent=4, sort_keys=True, ensure_ascii=False)

Нюансы и подводные камни

Типы данных JSON vs Python

PythonJSON
dictobject
listarray
strstring
intfloatnumber
Truetrue
Falsefalse
Nonenull

Сериализация объектов

Не все объекты можно сериализовать в JSON (например, datetime, пользовательские классы). Для них нужно писать кастомные энкодеры.

Частые ошибки и как их избежать

Ошибка 1: Забыл указать encoding

# Могут быть проблемы с русским текстом
with open('file.json', 'w') as file:
    json.dump(data, file)

# Всегда указывай utf-8
with open('file.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, ensure_ascii=False)

Ошибка 2: Путаница между dump и dumps

# dumps в файл (ошибка!)
json.dumps(data, file)

# dump для файла, dumps для строки
json.dump(data, file)  # В файл
json.dumps(data)       # В строку

Ошибка 3: Ошибка парсинга JSON

# Если строка невалидная — будет ошибка
invalid_json = '{"name": "Анна", age: 25}'  # age без кавычек
# json.loads(invalid_json)  # JSONDecodeError

# Используй try-except для безопасного парсинга
try:
    data = json.loads(invalid_json)
except json.JSONDecodeError:
    print("Ошибка: невалидный JSON")

Шпаргалка

Что нужноКак пишется
Записать в файлjson.dump(obj, file)
Прочитать из файлаjson.load(file)
Преобразовать в строкуjson.dumps(obj)
Преобразовать из строкиjson.loads(str)
Красивое форматированиеindent=4
Русский текст читаемоensure_ascii=False
Сортировка ключейsort_keys=True
Безопасный парсингtry: ... except json.JSONDecodeError

Заключение

Сегодня мы узнали:

  • Что такое JSON и зачем он нужен
  • Как записывать JSON в файл через json.dump()
  • Как читать JSON из файла через json.load()
  • Как преобразовывать объекты в строку через json.dumps()
  • Как парсить строки через json.loads()
  • Как настраивать форматирование (indent, ensure_ascii, sort_keys)

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×