Основные функции модуля json: практические примеры
Основы работы с библиотекой json
Наиболее эффективное решение для базовых операций с JSON в Python - использование функций json.dumps() для сериализации и json.loads() для десериализации.
import json
data = {"name": "Анна", "age": 30, "city": "Москва"}
json_string = json.dumps(data, ensure_ascii=False, indent=2)
print(json_string)
Python 3 json (работа с json в python 3)
{
"name": "Анна",
"age": 30,
"city": "Москва"
}
Json open python (открытие json файла в python)
Параметр ensure_ascii=False сохраняет кириллицу, indent=2 добавляет отступы. Для загрузки строки обратно в объект Python используется json.loads().
Как сериализовать данные с кастомными типами (например, datetime)?
По умолчанию json.dumps() не умеет обрабатывать объекты datetime. Для этого используется параметр default или создается собственный класс, наследующий от json.JSONEncoder.
import json
from datetime import datetime
def custom_serializer(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
data = {"now": datetime.now()}
json_str = json.dumps(data, default=custom_serializer, indent=2)
print(json_str)
преобразовать json в словарь python (преобразование json в словарь python)
{
"now": "2025-04-05T12:34:56.789012"
}
сохранить json python (сохранение json в файл python)
Проблема: Если не указать default, возникнет TypeError: Object of type datetime is not JSON serializable.
Решение: Определить функцию, преобразующую неподдерживаемые типы в строку или другой поддерживаемый формат, и передать её в параметр default.
Как загрузить JSON из файла?
Для чтения JSON из файла используется json.load(), которая принимает файловый объект.
with open("data.json", "r", encoding="utf-8") as f:
data = json.load(f)
print(data)
Python json lib (библиотека json в python)
Аналогично, json.dump() записывает данные в файл.
with open("output.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
вложенный json python (вложенный json в python)
Проблема: Если файл содержит некорректный JSON, возникнет json.JSONDecodeError. Также возможны проблемы с кодировкой, если не указать encoding.
Решение: Оборачивать чтение в try-except, указывать явно кодировку utf-8.
Как минимизировать размер JSON (убрать пробелы)?
Для передачи по сети или хранения в компактном виде используют параметр separators.
compact_json = json.dumps(data, separators=(',', ':'))
print(compact_json)
Json lines python (формат json lines в python)
{"name":"Анна","age":30,"city":"Москва"}
Python return json (возврат json из функции python)
Значение (',', ':') убирает все лишние пробелы. Это часто используется во фронтенд-приложениях.
Как отсортировать ключи в JSON?
Параметр sort_keys=True выводит ключи в алфавитном порядке.
sorted_json = json.dumps(data, sort_keys=True, indent=2)
print(sorted_json)
Как обработать ошибки при разборе JSON?
Используется исключение json.JSONDecodeError, которое наследуется от ValueError.
import json
try:
data = json.loads('{"invalid": "json"') # пропущена закрывающая скобка
except json.JSONDecodeError as e:
print(f"Ошибка разбора: {e}")
Ошибка разбора: Expecting property name enclosed in double quotes: line 1 column 17 (char 16)
Проблема: При разборе стороннего JSON может быть много неожиданных ошибок. Важно не просто игнорировать их, а логировать или обрабатывать соответствующим образом.
Как сериализовать объекты пользовательских классов?
Помимо параметра default, можно создать собственный класс, наследующий от json.JSONEncoder, переопределив метод default().
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
if isinstance(obj, bytes):
return obj.decode('utf-8')
return super().default(obj)
data = {"tags": {"python", "json", "encoding"}, "binary": b"hello"}
json_str = json.dumps(data, cls=MyEncoder, indent=2)
print(json_str)
{
"tags": ["encoding", "json", "python"],
"binary": "hello"
}
Проблема: Если не обработать тип, вызовется super().default(), который вызовет TypeError. Необходимо предусмотреть все типы, которые могут встретиться.
Расширенные примеры и нестандартные сценарии
Как выполнить глубокое копирование объекта через JSON?
import json
original = {"a": [1, 2, {"b": 3}]}
copy = json.loads(json.dumps(original))
original["a"][2]["b"] = 99
print(original) # {'a': [1, 2, {'b': 99}]}
print(copy) # {'a': [1, 2, {'b': 3}]}
{'a': [1, 2, {'b': 99}]}
{'a': [1, 2, {'b': 3}]}
Этот метод работает только для типов, представимых в JSON (словари, списки, строки, числа, булевы, None). Для других типов потребуется кастомная сериализация.
Как использовать object_hook для восстановления datetime?
import json
from datetime import datetime
def datetime_hook(pairs):
d = dict(pairs)
for key, value in d.items():
if isinstance(value, str) and 'T' in value:
try:
d[key] = datetime.fromisoformat(value)
except ValueError:
pass
return d
json_str = '{"event": "meeting", "time": "2025-04-05T15:30:00"}'
data = json.loads(json_str, object_hook=datetime_hook)
print(data)
print(type(data["time"])) #
{'event': 'meeting', 'time': datetime.datetime(2025, 4, 5, 15, 30)}
Как сериализовать Decimal с сохранением точности?
from decimal import Decimal
import json
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return str(obj)
return super().default(obj)
data = {"price": Decimal('19.99'), "quantity": Decimal('1000')}
json_str = json.dumps(data, cls=DecimalEncoder, indent=2)
print(json_str)
{
"price": "19.99",
"quantity": "1000"
}
При загрузке обратно можно написать кастомный парсер для восстановления Decimal.
Как пропустить нестроковые ключи при сериализации?
import json
data = {1: "one", (1,2): "tuple", "normal": "value"}
json_str = json.dumps(data, skipkeys=True)
print(json_str)
{"normal": "value"}
Параметр skipkeys=True игнорирует ключи, не являющиеся строками, числами или кортежами (кортежи преобразуются в строку).
Как обработать циклические ссылки?
import json
class Node:
def __init__(self, value):
self.value = value
self.child = None
node = Node(1)
node.child = node
def serializer(obj):
if isinstance(obj, Node):
return {"value": obj.value}
raise TypeError
try:
json.dumps(node, default=serializer)
except RecursionError:
print("Рекурсия при сериализации")
Стандартный JSON сериализатор не поддерживает циклические ссылки. Решение - либо избегать их, либо реализовать собственную логику с отслеживанием посещённых объектов.
Как использовать raw_decode для частичного парсинга?
import json
decoder = json.JSONDecoder()
data = '{"a": 1, "b": 2}{"c": 3}'
while data:
data = data.lstrip()
if not data:
break
obj, idx = decoder.raw_decode(data)
print(obj)
data = data[idx:]
{'a': 1, 'b': 2}
{'c': 3}
Это полезно для потоковой обработки нескольких JSON объектов в одном потоке.