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 и обратно, работа с более сложными структурами данных и настройка процесса для обработки особых случаев.
Помните: для освоения любой новой концепции и программного инструмента необходима практика. Поэтому воспользуйтесь возможностью поэкспериментировать с этими примерами, попробовав разные варианты.
Читайте также:
- JSON и Python: есть контакт!
- Прекратите использовать конфигурационные файлы JSON
- Подробный обзор JSON, JSON5 и циклических зависимостей
Читайте нас в Telegram, VK и Дзен
Перевод статьи Soner Yıldırım: 10 Examples to Learn the JSON module of Python