Json.dumps: примеры (PYTHON)
json.dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys): strОсновы функции json.dumps
Функция json.dumps() является частью стандартного модуля json в Python. Ее основное назначение – сериализация (преобразование) объекта Python в строку формата JSON (JavaScript Object Notation). Эта операция называется кодированием или дампом.
Использование функции актуально при необходимости передать данные по сети, сохранить их в файл или подготовить для систем, которые понимают формат JSON, например, веб-API или базы данных.
Сигнатура функции: json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
- obj: Объект Python для сериализации (например, dict, list, str, int, float, bool, None).
- skipkeys (по умолчанию False): Если True, пропускает ключи словаря, не являющиеся базовыми типами (str, int, float, bool, None). В противном случае вызывает TypeError.
- ensure_ascii (по умолчанию True): Если True, все не-ASCII символы в выводе экранируются последовательностями \uXXXX. Если False, они записываются как есть.
- check_circular (по умолчанию True): Проверка на циклические ссылки в объекте. При обнаружении вызывает OverflowError.
- allow_nan (по умолчанию True): Разрешает сериализацию значений float('nan'), float('inf'), float('-inf'). Если False, вызывает ValueError.
- cls (по умолчанию None): Можно указать пользовательский класс-кодировщик (наследник json.JSONEncoder) для обработки нестандартных типов.
- indent (по умолчанию None): Определяет отступ для вложенных структур. Может быть целым числом (количество пробелов) или строкой (например, '\t').
- separators (по умолчанию (', ', ': ')): Кортеж из двух строк, определяющих разделитель элементов списка и разделитель ключа и значения в словаре.
- default (по умолчанию None): Функция, которая вызывается для объектов, не сериализуемых стандартным образом. Должна возвращать сериализуемый объект или вызывать TypeError.
- sort_keys (по умолчанию False): Если True, ключи словаря в выводе сортируются в лексикографическом порядке.
Функция возвращает строку типа str, содержащую JSON-представление объекта.
Простые примеры использования
Базовый пример сериализации словаря:
import json
simple_dict = {"name": "Alice", "age": 30, "city": "Moscow"}
result = json.dumps(simple_dict)
print(result){"name": "Alice", "age": 30, "city": "Moscow"}Использование параметра indent для красивого вывода:
result = json.dumps(simple_dict, indent=2)
print(result){
"name": "Alice",
"age": 30,
"city": "Moscow"
}Использование параметра sort_keys:
result = json.dumps(simple_dict, sort_keys=True, indent=2)
print(result){
"age": 30,
"city": "Moscow",
"name": "Alice"
}Работа с не-ASCII символами и параметром ensure_ascii:
data = {"city": "Санкт-Петербург"}
print(json.dumps(data))
print(json.dumps(data, ensure_ascii=False)){"city": "\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433"}
{"city": "Санкт-Петербург"}Похожие функции в Python
В модуле json существуют другие функции для работы с сериализацией.
- json.dump(obj, fp, ...): Аналогична
dumps(), но записывает результат не в строку, а непосредственно в файловый объект (например, открытый файл). Ее удобно использовать для сохранения данных на диск. - json.JSONEncoder: Класс-кодировщик, логику которого можно наследовать и переопределять. Функция
json.dumps()внутри использует этот класс. Прямое использование класса целесообразно для сложного кастомного кодирования множества типов.
json.dumps() предпочтительнее, когда результат нужен в виде строки в памяти (для отправки по HTTP, формирования ответа API). json.dump() эффективнее для прямой записи в файл, так как не создает промежуточную большую строку.
Аналоги функции в других языках
JavaScript: JSON.stringify(). Функция очень похожа, но имеет различия в параметрах (пространство для отступа, функция замены).
const obj = { name: "Alice", age: 30 };
console.log(JSON.stringify(obj));
console.log(JSON.stringify(obj, null, 2));{"name":"Alice","age":30}
{
"name": "Alice",
"age": 30
}PHP: json_encode(). Возвращает строку JSON. Флаги управления поведением передаются в виде битовой маски.
$arr = ["name" => "Alice", "age" => 30];
echo json_encode($arr);
echo json_encode($arr, JSON_PRETTY_PRINT);{"name":"Alice","age":30}
{
"name": "Alice",
"age": 30
}Java (библиотека Jackson): Используется объект ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(myObject);
// Для красивого вывода:
mapper.enable(SerializationFeature.INDENT_OUTPUT);Golang: json.Marshal() возвращает байтовый срез и ошибку. Для отступов используют json.MarshalIndent().
type Person struct { Name string `json:"name"` }
data := Person{Name: "Alice"}
b, _ := json.Marshal(data)
fmt.Println(string(b)){"name":"Alice"}Типичные ошибки
Ошибка сериализации несериализуемого типа:
import json
import datetime
data = {"time": datetime.datetime.now()}
try:
json.dumps(data)
except TypeError as e:
print(f"Ошибка: {e}")Ошибка: Object of type datetime is not JSON serializable
Ошибка при allow_nan=False:
data = {"value": float('nan')}
try:
json.dumps(data, allow_nan=False)
except ValueError as e:
print(f"Ошибка: {e}")Ошибка: Out of range float values are not JSON compliant
Проблема с циклической ссылкой при check_circular=True (по умолчанию):
a = {}
b = {'ref': a}
a['ref'] = b # Циклическая ссылка
try:
json.dumps(a)
except OverflowError as e:
print(f"Ошибка: {e}")Ошибка: Circular reference detected
Изменения в последних версиях
- В Python 3.9 добавлен параметр
defaultвjson.JSONEncoderдля более удобного переопределения. - Начиная с Python 3.6, параметр
object_hook(и аналоги) стали вызываться для всех типов словарей, а не только дляdict. - В Python 3.4 параметр
indentстал принимать строку в качестве значения для пользовательского отступа (например, '\t'). - В Python 3.2 добавлена возможность использования разделителей без пробелов через параметр
separators=(',', ':')для более компактного вывода.
Расширенные примеры
Использование функции default для обработки пользовательских классов:
import json
from datetime import datetime
class User:
def __init__(self, name, reg_date):
self.name = name
self.reg_date = reg_date
def custom_encoder(obj):
if isinstance(obj, User):
return {'name': obj.name, 'reg_date': obj.reg_date.isoformat()}
elif isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Type {type(obj)} not serializable")
user = User("Bob", datetime.now())
data = {"user": user, "timestamp": datetime.now()}
result = json.dumps(data, default=custom_encoder, indent=2)
print(result){
"user": {
"name": "Bob",
"reg_date": "2023-10-26T15:30:00.123456"
},
"timestamp": "2023-10-26T15:30:00.123456"
}Создание максимально компактного JSON (без лишних пробелов):
data = [{"a": 1}, {"b": 2}]
result = json.dumps(data, separators=(',', ':'))
print(repr(result))'[{"a":1},{"b":2}]'Использование параметра skipkeys:
data = {("tuple", "key"): "value", "normal_key": 123}
result = json.dumps(data, skipkeys=True)
print(result){"normal_key": 123}Кастомный класс-кодировщик для сложных сценариев:
import json
class ComplexEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, complex):
return {"__type__": "complex", "real": obj.real, "imag": obj.imag}
return super().default(obj)
data = {"number": 3+4j}
result = json.dumps(data, cls=ComplexEncoder)
print(result){"number": {"__type__": "complex", "real": 3.0, "imag": 4.0}}