json — Кодировщик и декодировщик JSON

Источник: Lib/json/__init__.py


JSON (JavaScript Object Notation), определяемый RFC 7159 (который отменяет RFC 4627) и ECMA-404, представляет собой облегченный формат обмена данными, вдохновленный синтаксисом объектных литералов JavaScript (хотя он не является строгим подмножеством JavaScript [1] ).

Предупреждение

Будьте осторожны при разборе данных JSON из ненадежных источников. Вредоносная строка JSON может привести к тому, что декодер будет потреблять значительные ресурсы процессора и памяти. Рекомендуется ограничить размер данных для разбора.

json предоставляет API, знакомый пользователям стандартной библиотеки marshal и модулей pickle.

Кодирование основных иерархий объектов Python:

>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'

Компактное кодирование:

>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'

Красивая печать:

>>> import json
>>> print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4))
{
    "4": 5,
    "6": 7
}

Специализация кодирования объектов JSON:

>>> import json
>>> def custom_json(obj):
...     if isinstance(obj, complex):
...         return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
...     raise TypeError(f'Cannot serialize object of {type(obj)}')
...
>>> json.dumps(1 + 2j, default=custom_json)
'{"__complex__": true, "real": 1.0, "imag": 2.0}'

Декодирование JSON:

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']

Специализация декодирования объектов JSON:

>>> import json
>>> def as_complex(dct):
...     if '__complex__' in dct:
...         return complex(dct['real'], dct['imag'])
...     return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
...     object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')

Расширение JSONEncoder:

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         # Let the base class default method raise the TypeError
...         return super().default(obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[2.0', ', 1.0', ']']

Использование json.tool из оболочки для проверки и красивой печати:

$ echo '{"json":"obj"}' | python -m json.tool
{
    "json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Подробную документацию см. в разделе Интерфейс командной строки.

Примечание

JSON является подмножеством YAML. 1.2. JSON, созданный с помощью настроек модуля по умолчанию (в частности, значение separators по умолчанию), также является подмножеством YAML 1.0 и 1.1. Таким образом, этот модуль можно использовать в качестве сериализатора YAML.

Примечание

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

Базовое использование

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

Сериализуйте obj в виде потока с форматом JSON на fp (поддерживающий .write()), используя этот conversion table.

Если значение skipkeys равно true (по умолчанию: False), то ключи диктовки, не относящиеся к базовому типу (str, int, float, bool, None), будут пропущены вместо того, чтобы вызвать сообщение TypeError.

Модуль json всегда производит объекты str, а не bytes. Поэтому модуль fp.write() должен поддерживать ввод str.

Если ensure_ascii равно true (по умолчанию), то гарантируется, что все входящие символы, не относящиеся к ASCII, будут экранированы. Если ensure_ascii равно false, эти символы будут выведены как есть.

Если check_circular равно false (по умолчанию: True), то проверка круговой ссылки для типов контейнеров будет пропущена, и круговая ссылка приведет к RecursionError (или еще хуже).

Если allow_nan - false (по умолчанию: True), то будет использоваться ValueError для сериализации значений вне диапазона float (nan, inf, -inf) в строгом соответствии со спецификацией JSON. Если значение allow_nan равно true, то будут использоваться их эквиваленты в JavaScript (NaN, Infinity, -Infinity).

Если indent - неотрицательное целое число или строка, то элементы массива JSON и члены объекта будут напечатаны с этим уровнем отступа. Уровень отступа, равный 0, отрицательный или "", будет вставлять только новые строки. None (по умолчанию) выбирает наиболее компактное представление. При использовании целого положительного числа отступ составляет столько-то пробелов на уровень. Если indent - это строка (например, "\t"), то эта строка используется для отступа каждого уровня.

Изменено в версии 3.2: Разрешите использовать строки для indent в дополнение к целым числам.

Если указано, разделители должны быть кортежем (item_separator, key_separator). По умолчанию используется значение (', ', ': '), если indent равен None, и (',', ': ') в противном случае. Для получения наиболее компактного представления JSON следует указать (',', ':'), чтобы исключить пробельные символы.

Изменено в версии 3.4: Используйте (',', ': ') по умолчанию, если значение indent не равно None.

Если указано, default должна быть функцией, которая вызывается для объектов, которые не могут быть сериализованы иным способом. Она должна возвращать JSON-кодируемую версию объекта или вызывать сообщение TypeError. Если не указано, будет вызвана TypeError.

Если значение sort_keys равно true (по умолчанию: False), то вывод словарей будет отсортирован по ключу.

Чтобы использовать собственный подкласс JSONEncoder (например, тот, который переопределяет метод default() для сериализации дополнительных типов), укажите его с помощью карг cls; в противном случае используется JSONEncoder.

Изменено в версии 3.6: Все необязательные параметры теперь имеют значение keyword-only.

Примечание

В отличие от pickle и marshal, JSON не является фреймовым протоколом, поэтому попытка сериализовать несколько объектов при повторных вызовах dump() с использованием одного и того же fp приведет к созданию недействительного JSON-файла.

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 в формат JSON str с помощью этого conversion table. Аргументы имеют то же значение, что и в dump().

Примечание

Ключи в парах ключ/значение в JSON всегда имеют тип str. Когда словарь преобразуется в JSON, все ключи словаря преобразуются в строки. В результате этого, если словарь преобразовать в JSON, а затем обратно в словарь, то словарь может не совпадать с исходным. То есть loads(dumps(x)) != x, если x имеет нестроковые ключи.

json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

Десериализуйте fp (.read()-поддерживающий text file или binary file, содержащий JSON-документ) в объект Python с помощью этого conversion table.

object_hook - это необязательная функция, которая будет вызвана с результатом декодирования любого объектного литерала (символ dict). Возвращаемое значение object_hook будет использовано вместо dict. Эта функция может быть использована для реализации пользовательских декодеров (например, подсказки класса JSON-RPC).

object_pairs_hook - это необязательная функция, которая будет вызвана с результатом декодирования любого объектного литерала в упорядоченный список пар. Возвращаемое значение object_pairs_hook будет использовано вместо dict. Эта возможность может быть использована для реализации пользовательских декодеров. Если object_hook также определен, то object_pairs_hook имеет приоритет.

Изменено в версии 3.1: Добавлена поддержка object_pairs_hook.

parse_float, если указано, будет вызываться со строкой каждого JSON float, который нужно декодировать. По умолчанию это эквивалентно float(num_str). Это может быть использовано для использования другого типа данных или парсера для JSON float (например, decimal.Decimal).

parse_int, если указано, будет вызываться со строкой каждого JSON int, который нужно декодировать. По умолчанию это эквивалентно int(num_str). Это может быть использовано для использования другого типа данных или парсера для целых чисел JSON (например, float).

Изменено в версии 3.11: Значение по умолчанию parse_int int() теперь ограничивает максимальную длину целочисленной строки через integer string conversion length limitation интерпретатора, что помогает избежать атак типа «отказ в обслуживании».

parse_constant, если указан, будет вызван с одной из следующих строк: '-Infinity', 'Infinity', 'NaN'. Это можно использовать для того, чтобы вызвать исключение, если встречаются недопустимые числа JSON.

Изменено в версии 3.1: parse_constant больше не вызывается для „null“, „true“, „false“.

Чтобы использовать собственный подкласс JSONDecoder, укажите его с помощью ключевого слова cls; в противном случае используется JSONDecoder. Дополнительные аргументы ключевого слова будут переданы в конструктор класса.

Если десериализуемые данные не являются корректным JSON-документом, будет выдано сообщение JSONDecodeError.

Изменено в версии 3.6: Все необязательные параметры теперь имеют значение keyword-only.

Изменено в версии 3.6: fp теперь может быть binary file. Входная кодировка должна быть UTF-8, UTF-16 или UTF-32.

json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

Десериализуйте s (экземпляр str, bytes или bytearray, содержащий JSON-документ) в объект Python с помощью этого conversion table.

Остальные аргументы имеют то же значение, что и в load().

Если десериализуемые данные не являются корректным JSON-документом, будет выдано сообщение JSONDecodeError.

Изменено в версии 3.6: Теперь s может иметь тип bytes или bytearray. Входная кодировка должна быть UTF-8, UTF-16 или UTF-32.

Изменено в версии 3.9: Ключевой аргумент encoding был удален.

Кодирующие и декодирующие устройства

class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)

Простой декодер JSON.

По умолчанию при декодировании выполняются следующие переводы:

JSON

Python

объект

диктант

массив

список

строка

str

число (int)

int

число (вещественное)

float

правда

Правда

ложь

Ложь

null

Нет

Он также понимает NaN, Infinity и -Infinity как соответствующие им значения float, что выходит за рамки спецификации JSON.

object_hook, если указан, будет вызываться с результатом декодирования каждого JSON-объекта, и его возвращаемое значение будет использоваться вместо заданного dict. Это может быть использовано для обеспечения пользовательской десериализации (например, для поддержки подсказок класса JSON-RPC).

object_pairs_hook, если он указан, будет вызван с результатом декодирования каждого JSON-объекта в упорядоченный список пар. Возвращаемое значение object_pairs_hook будет использовано вместо dict. Эта возможность может быть использована для реализации пользовательских декодеров. Если object_hook также определен, то object_pairs_hook имеет приоритет.

Изменено в версии 3.1: Добавлена поддержка object_pairs_hook.

parse_float, если указано, будет вызываться со строкой каждого JSON float, который нужно декодировать. По умолчанию это эквивалентно float(num_str). Это может быть использовано для использования другого типа данных или парсера для JSON float (например, decimal.Decimal).

parse_int, если указано, будет вызываться со строкой каждого JSON int, который нужно декодировать. По умолчанию это эквивалентно int(num_str). Это может быть использовано для использования другого типа данных или парсера для целых чисел JSON (например, float).

parse_constant, если указан, будет вызван с одной из следующих строк: '-Infinity', 'Infinity', 'NaN'. Это можно использовать для того, чтобы вызвать исключение, если встречаются недопустимые числа JSON.

Если значение strict равно false (по умолчанию``True``), то в строках будут разрешены управляющие символы. Управляющие символы в данном контексте - это символы с кодами в диапазоне 0–31, включая '\t' (табуляция), '\n', '\r' и '\0'.

Если десериализуемые данные не являются корректным JSON-документом, будет выдано сообщение JSONDecodeError.

Изменено в версии 3.6: Все параметры теперь равны keyword-only.

decode(s)

Возвращает Python-представление s (экземпляр str, содержащий JSON-документ).

JSONDecodeError будет поднята, если данный JSON-документ не является валидным.

raw_decode(s)

Декодирует JSON-документ из s (str, с которого начинается JSON-документ) и возвращает 2-кортеж из Python-представления и индекса в s, на котором закончился документ.

Это можно использовать для декодирования JSON-документа из строки, которая может содержать посторонние данные в конце.

class json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Расширяемый кодировщик JSON для структур данных Python.

По умолчанию поддерживает следующие объекты и типы:

Python

JSON

диктант

объект

список, кортеж

массив

str

строка

int, float, int- и float-производные Enums

номер

Правда

правда

Ложь

ложь

Нет

null

Изменено в версии 3.4: Добавлена поддержка классов Enum, производных от int и float.

Чтобы расширить эту функцию для распознавания других объектов, создайте подкласс и реализуйте метод default() с другим методом, который возвращает сериализуемый объект для o, если это возможно, иначе он должен вызывать реализацию суперкласса (чтобы поднять TypeError).

Если skipkeys равно false (по умолчанию), то при попытке закодировать ключи, которые не являются str, int, float или None, будет возникать ошибка TypeError. Если значение skipkeys равно true, такие элементы будут просто пропущены.

Если ensure_ascii равно true (по умолчанию), то гарантируется, что все входящие символы, не относящиеся к ASCII, будут экранированы. Если ensure_ascii равно false, эти символы будут выведены как есть.

Если значение check_circular равно true (по умолчанию), то списки, кубики и пользовательские кодированные объекты будут проверяться на наличие круговых ссылок во время кодирования, чтобы предотвратить бесконечную рекурсию (которая приведет к появлению RecursionError). В противном случае такая проверка не производится.

Если значение allow_nan равно true (по умолчанию), то NaN, Infinity и -Infinity будут закодированы как таковые. Такое поведение не соответствует спецификации JSON, но согласуется с большинством кодировщиков и декодировщиков на основе JavaScript. В противном случае для кодирования таких плавающих чисел потребуется ValueError.

Если значение sort_keys равно true (по умолчанию: False), то вывод словарей будет отсортирован по ключу; это полезно для регрессионных тестов, чтобы убедиться, что сериализации JSON можно сравнивать на ежедневной основе.

Если indent - неотрицательное целое число или строка, то элементы массива JSON и члены объекта будут напечатаны с этим уровнем отступа. Уровень отступа, равный 0, отрицательный или "", будет вставлять только новые строки. None (по умолчанию) выбирает наиболее компактное представление. При использовании целого положительного числа отступ составляет столько-то пробелов на уровень. Если indent - это строка (например, "\t"), то эта строка используется для отступа каждого уровня.

Изменено в версии 3.2: Разрешите использовать строки для indent в дополнение к целым числам.

Если указано, разделители должны быть кортежем (item_separator, key_separator). По умолчанию используется значение (', ', ': '), если indent равен None, и (',', ': ') в противном случае. Для получения наиболее компактного представления JSON следует указать (',', ':'), чтобы исключить пробельные символы.

Изменено в версии 3.4: Используйте (',', ': ') по умолчанию, если значение indent не равно None.

Если указано, default должна быть функцией, которая вызывается для объектов, которые не могут быть сериализованы иным способом. Она должна возвращать JSON-кодируемую версию объекта или вызывать сообщение TypeError. Если не указано, будет вызвана TypeError.

Изменено в версии 3.6: Все параметры теперь равны keyword-only.

default(o)

Реализуйте этот метод в подклассе таким образом, чтобы он возвращал сериализуемый объект для o, либо вызывал базовую реализацию (чтобы поднять TypeError).

Например, для поддержки произвольных итераторов вы можете реализовать default() следующим образом:

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   # Let the base class default method raise the TypeError
   return super().default(o)
encode(o)

Возвращает строковое представление JSON структуры данных Python, o. Например:

>>> json.JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
iterencode(o)

Закодируйте заданный объект, o, и выдайте каждое доступное строковое представление. Например:

for chunk in json.JSONEncoder().iterencode(bigobject):
    mysocket.write(chunk)

Исключения

exception json.JSONDecodeError(msg, doc, pos)

Подкласс ValueError со следующими дополнительными атрибутами:

msg

Неформатированное сообщение об ошибке.

doc

Разбираемый документ JSON.

pos

Начальный индекс doc, при разборе которого произошел сбой.

lineno

Строка, соответствующая pos.

colno

Столбец, соответствующий pos.

Added in version 3.5.

Соответствие стандартам и совместимость

Формат JSON задается символами RFC 7159 и ECMA-404. В этом разделе подробно описывается уровень соответствия данного модуля RFC. Для простоты подклассы JSONEncoder и JSONDecoder, а также параметры, кроме явно указанных, не рассматриваются.

Этот модуль не соответствует RFC в строгом смысле, реализуя некоторые расширения, которые являются допустимыми JavaScript, но не являются допустимыми JSON. В частности:

  • Принимаются и выводятся значения бесконечных чисел и NaN;

  • Повторяющиеся имена внутри объекта принимаются, и используется только значение последней пары имя-значение.

Поскольку RFC разрешает RFC-совместимым парсерам принимать входные тексты, которые не являются RFC-совместимыми, десериализатор этого модуля технически является RFC-совместимым при настройках по умолчанию.

Кодировки символов

RFC требует, чтобы JSON был представлен с использованием UTF-8, UTF-16 или UTF-32, при этом UTF-8 рекомендуется по умолчанию для максимальной совместимости.

Как разрешено, хотя и не требуется RFC, сериализатор этого модуля по умолчанию устанавливает ensure_ascii=True, тем самым экранируя вывод так, чтобы результирующие строки содержали только символы ASCII.

За исключением параметра ensure_ascii, этот модуль определен строго с точки зрения преобразования между объектами Python и Unicode strings, и поэтому не затрагивает напрямую вопрос о кодировках символов.

RFC запрещает добавлять метку порядка байтов (BOM) в начало текста JSON, и сериализатор этого модуля не добавляет BOM в свой вывод. RFC разрешает, но не требует, чтобы десериализаторы JSON игнорировали начальный BOM на своем входе. Десериализатор этого модуля выдает ошибку ValueError, если начальный BOM присутствует.

RFC не запрещает в явном виде строки JSON, содержащие последовательности байтов, которые не соответствуют действительным символам Юникода (например, непарные суррогаты UTF-16), но отмечает, что они могут вызвать проблемы с совместимостью. По умолчанию этот модуль принимает и выводит (при наличии в исходном str) кодовые точки для таких последовательностей.

Бесконечные и NaN-значения чисел

RFC не разрешает представлять бесконечные или NaN-значения чисел. Несмотря на это, по умолчанию модуль принимает и выводит Infinity, -Infinity и NaN так, как если бы они были допустимыми значениями литерала числа JSON:

>>> # Neither of these calls raises an exception, but the results are not valid JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # Same when deserializing
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan

В сериализаторе для изменения этого поведения можно использовать параметр allow_nan. В десериализаторе для изменения этого поведения можно использовать параметр parse_constant.

Повторяющиеся имена внутри объекта

RFC определяет, что имена внутри JSON-объекта должны быть уникальными, но не указывает, как следует обрабатывать повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не вызывает исключения; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:

>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}

Параметр object_pairs_hook может быть использован для изменения этого поведения.

Значения верхнего уровня, не относящиеся к объектам и массивам

Старая версия JSON, указанная в устаревшем RFC 4627, требовала, чтобы значение верхнего уровня текста JSON было либо объектом JSON, либо массивом (Python dict или list) и не могло быть значением JSON null, boolean, number или string. В RFC 7159 это ограничение снято, и данный модуль не реализует и никогда не реализовывал это ограничение ни в своем сериализаторе, ни в своем десериализаторе.

Независимо от этого, для обеспечения максимальной совместимости вы можете сами добровольно придерживаться этого ограничения.

Ограничения при реализации

Некоторые реализации десериализаторов JSON могут устанавливать ограничения:

  • размер принимаемых текстов JSON

  • максимальный уровень вложенности объектов и массивов JSON

  • диапазон и точность чисел JSON

  • содержание и максимальная длина строк JSON

Этот модуль не накладывает никаких ограничений, кроме тех, которые существуют в самих соответствующих типах данных Python или в самом интерпретаторе Python.

При сериализации в JSON следует помнить о наличии подобных ограничений в приложениях, которые могут потреблять ваш JSON. В частности, часто числа JSON десериализуются в числа двойной точности IEEE 754 и, таким образом, подвергаются ограничениям на диапазон и точность этого представления. Это особенно актуально при сериализации значений Python int очень большой величины или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal.

Интерфейс командной строки

Источник: Lib/json/tool.py


Модуль json.tool предоставляет простой интерфейс командной строки для проверки и красивой печати JSON-объектов.

Если необязательные аргументы infile и outfile не указаны, будут использоваться sys.stdin и sys.stdout соответственно:

$ echo '{"json": "obj"}' | python -m json.tool
{
    "json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Изменено в версии 3.5: Теперь выходные данные расположены в том же порядке, что и входные. Используйте опцию --sort-keys, чтобы отсортировать вывод словарей в алфавитном порядке по ключу.

Параметры командной строки

infile

JSON-файл, который необходимо проверить или распечатать:

$ python -m json.tool mp_films.json
[
    {
        "title": "And Now for Something Completely Different",
        "year": 1971
    },
    {
        "title": "Monty Python and the Holy Grail",
        "year": 1975
    }
]

Если infile не указан, читаем из sys.stdin.

outfile

Запись вывода из infile в заданный outfile. В противном случае запишите его в sys.stdout.

--sort-keys

Сортировка вывода словарей в алфавитном порядке по ключу.

Added in version 3.5.

--no-ensure-ascii

Отключите экранирование неасквидных символов, см. дополнительную информацию в разделе json.dumps().

Added in version 3.9.

--json-lines

Разберите каждую строку ввода как отдельный JSON-объект.

Added in version 3.8.

--indent, --tab, --no-indent, --compact

Взаимоисключающие опции для контроля пробельных символов.

Added in version 3.9.

-h, --help

Показать сообщение о помощи.

Сноски