Json.dumps: примеры (PYTHON)

Использование json.dumps для работы с JSON в Python
Раздел: JSON, Сериализация
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 для обработки пользовательских классов:

Пример python
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 (без лишних пробелов):

Пример python
data = [{"a": 1}, {"b": 2}]
result = json.dumps(data, separators=(',', ':'))
print(repr(result))
'[{"a":1},{"b":2}]'

Использование параметра skipkeys:

Пример python
data = {("tuple", "key"): "value", "normal_key": 123}
result = json.dumps(data, skipkeys=True)
print(result)
{"normal_key": 123}

Кастомный класс-кодировщик для сложных сценариев:

Пример python
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}}

питон json.dumps function comments

En
Json.dumps Serialize object to JSON string