JSON, что означает JavaScript Object Notation (нотация объектов JavaScript), является часто используемым форматом файлов (или данных). Созданный на основе JavaScript, JSON не зависит от языка: большинство языков программирования имеют парсеры для работы с файлами JSON.

JSON можно рассматривать как коллекцию пар ключ-значение, как и словарь в Python.

Вот простой файл JSON:

{"name": "Jane", "age": 28, "city": "Houston"}

Приведенный выше код  —  наглядный пример того, что JSON является человекочитаемым: вы можете прочитать JSON-файл и понять, какие данные он содержит. Он также легко парсится и генерируется машинами.


Почему JSON так популярен?

Широкому использованию JSON в разработке программного обеспечения и программировании способствуют многочисленные факторы. Перечислим некоторые из них.

  • Удобство чтения. Как видно из приведенного выше примера, JSON легко читать и писать, что делает его отличным выбором для хранения данных, которые нужно сделать человекочитаемыми.
  • Легкость. JSON не очень многословен, что облегчает его передачу по сети, а также ускоряет парсинг и загрузку.
  • Структура. Это структурированный формат для хранения данных, легко читаемый людьми и машинами.
  • Интероперабельность. JSON не зависит от языка и может быть использован в любом языке, а не только в JavaScript. Поэтому он отлично подходит для обмена данными между различными языками программирования.

Работа с JSON в Python

Встроенный в Python модуль json обеспечивает простой и эффективный способ работы с форматом JSON. Рассмотрим 10 примеров, демонстрирующих общие задачи, которые можно выполнять с помощью этого модуля.

Пример 1. Преобразование объекта Python в строку JSON

import json

data = {
"name": "John Doe",
"age": 28,
"city": "Houston"
}

json_data = json.dumps(data)
print(json_data)

# вывод
{"name": "John Doe", "age": 28, "city": "Houston"}

Метод dumps преобразует словарь в строку в формате json. Поэтому приведенный выше тип переменной json_data становится строкой.

type(json_data)

# вывод
str

Пример 2. Красивый вывод JSON

import json

data = {
"name": "John Doe",
"age": 28,
"city": "Houston"
}

json_data = json.dumps(data, indent=4)
print(json_data)

# вывод
{
"name": "John Doe",
"age": 28,
"city": "Houston"
}

Использование параметра indent позволяет сделать файл более читабельным.


Пример 3. Сортировка ключей

import json

data = {
"name": "John Doe",
"age": 28,
"city": "Houston"
}

json_data = json.dumps(data, sort_keys=True, indent=4)
print(json_data)

# вывод
{
"age": 28,
"city": "Houston",
"name": "John Doe"
}

Напомним, что файл JSON представляет собой набор пар ключ-значение. Вы можете сортировать эти пары по ключам с помощью параметра sort_keys.


Пример 4. Загрузка JSON в объект Python

import json

json_data = '{"name": "John Doe", "age": 28, "city": "Houston"}'
data = json.loads(json_data)

print(data)
print(data['name']) # Доступ к значению ключа 'name'

# вывод
{'name': 'John Doe', 'age': 28, 'city': 'Houston'}
John Doe

Возьмем файл JSON, сохраненный в виде строки. Преобразуем его в объект Python типа dictionary с помощью функции loads. Проверим тип этого файла.

type(data)

# вывод
dict

Пример 5. Запись контента Python в JSON-файл

import json

data = {
"name": "John Doe",
"age": 28,
"city": "Houston"
}

with open('data.json', 'w') as file:
json.dump(data, file)

В этом примере у нас есть словарь Python под названием data. Используем метод dump для записи его контента в файл JSON с именем data.json, который выглядит следующим образом:

Изображение автора

Пример 6. Передача данных из файла JSON

import json

with open('data.json', 'r') as file:
data = json.load(file)

print(data)

# вывод
{'name': 'John Doe', 'age': 28, 'city': 'Houston'}

Метод load позволяет передать контент файла JSON в словарь Python.


Пример 7. Параметр default

Параметр default функции dumps можно использовать для сериализации сложных объектов Python, которые иначе не могут быть сериализованы. Например, следующий код вызывает ошибку TypeError из-за объекта datetime:

import json

data = {
"name": "John Doe",
"age": 28,
"city": "Houston",
"birthday": datetime.datetime.now()
}

json_data = json.dumps(data, indent=4)

# вывод
TypeError: Object of type datetime is not JSON serializable

Чтобы избежать этой ошибки, следует написать пользовательскую функцию, которая указывает функции dumps, как сериализовать этот объект:

import json
import datetime

def datetime_serializer(x):
if isinstance(x, datetime.datetime):
return x.isoformat()

data = {
"name": "John Doe",
"age": 28,
"city": "Houston",
"birthday": datetime.datetime.now()
}

json_data = json.dumps(data, indent=4, default=datetime_serializer)
print(json_data)

# вывод
{
"name": "John Doe",
"age": 28,
"city": "Houston",
"birthday": "2023-05-14T07:22:53.917531"
}

Пример 8. Параметр default и пользовательский класс

Допустим, есть пользовательский класс Person, и его нужно преобразовать экземпляр в JSON.

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

person = Person("John", 30)
json.dumps(person) # Вызывает TypeError

# вывод
ypeError: Object of type Person is not JSON serializable

Можно определить функцию, указывающую, как сериализовать объект Person:

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

def person_to_dict(person):
return {"name": person.name, "age": person.age}

person = Person("John", 30)
json.dumps(person, default=person_to_dict)

# вывод
'{"name": "John", "age": 30}'

Пример 9. JSONEncoder

Класс JSONEncoder предоставляет больше контроля над процессом сериализации при преобразовании сложного объекта Python в JSON. Вместо того чтобы использовать функцию default, для json.dumps() можно создать подкласс JSONEncoder и переопределить его метод default().

Возьмем тот же пример с классом Person, но используем JSONEncoder вместо параметра default.

import json

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

class PersonEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Person):
return {'name': o.name, 'age': o.age}
return super().default(o)

person = Person("John", 30)
json.dumps(person, cls=PersonEncoder)

# вывод
'{"name": "John", "age": 30}'

PersonEncoder является подклассом, который наследуется от JSONEncoder.


Пример 10. Параметр skipkeys

Параметр skipkeys в dumps используется для указания того, что следует пропускать ключи, не относящиеся к основным типам (str, int, float, bool, None), вместо того, чтобы выдавать ошибку TypeError. Это удобно при работе с большими файлами.

Рассмотрим пример с использованием кортежа в качестве ключа:

import json

data = {
(1, 2): "tuple_key",
"normal_key": "value"
}

print(json.dumps(data))

# вывод
TypeError: keys must be str, int, float, bool or None, not tuple

Как видно из вывода, возникает ошибка TypeError. Если установить значение параметра skipkeys равным True, ключ кортежа будет пропущен без возникновения ошибки.

import json

data = {
(1,2): "tuple_key", # кортежи как ключи являются не JSON-сериализуемыми
"normal_key": "value"
}
print(json.dumps(data, skipkeys=True))

# вывод
{"normal_key": "value"}

Заключение

Мы познакомились с модулем json, который является мощным инструментом языка Python для работы с данными JSON. Он предоставляет функции и методы с высокой степенью гибкости и контроля над процессом сериализации и десериализации.

Примеры в этой статье охватывают такие темы, как преобразование объектов Python в JSON и обратно, работа с более сложными структурами данных и настройка процесса для обработки особых случаев.

Помните: для освоения любой новой концепции и программного инструмента необходима практика. Поэтому воспользуйтесь возможностью поэкспериментировать с этими примерами, попробовав разные варианты.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Soner Yıldırım: 10 Examples to Learn the JSON module of Python

Предыдущая статьяScyllaDB в K8S: как справляться с интенсивными рабочими нагрузками на спотовых экземплярах без простоев
Следующая статьяСостояние инфраструктуры данных на 2023 год  —  ключевые тренды ландшафта MAD от Мэтта Терка