Документация Python неофициальный перевод
Содержание страницы

18.2. json – кодировщик и декодировщик JSONjson – JSON encoder and decoder

Новое в версии 2.6.

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

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(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO 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({'4': 5, '6': 7}, sort_keys=True,
...                  indent=4, separators=(',', ': '))
{
    "4": 5,
    "6": 7
}

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

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'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]
...         # Пусть метод базового класса по умолчанию возбуждает TypeError
...         return json.JSONEncoder.default(self, 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 -mjson.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.

18.2.1. Основное использованиеBasic Usage

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

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

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

Если ensure_ascii равен true (по умолчанию), то все не-ASCII символы в выводе экранируются последовательностями \uXXXX, и результатом является экземпляр str, состоящий только из символов ASCII. Если ensure_ascii равен false, некоторые блоки, записанные в fp, могут быть экземплярами unicode. Обычно это происходит из-за того, что входные данные содержат строки unicode или используется параметр encoding. Если только fp.write() явно не понимает unicode (как в codecs.getwriter()), это, скорее всего, вызовет ошибку.

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

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

Если indent – неотрицательное целое число, то элементы массива JSON и члены объекта будут красиво отформатированы с этим уровнем отступа. Уровень отступа 0 или отрицательное значение вставляет только новые строки. None (по умолчанию) выбирает наиболее компактное представление.

Примечание

Поскольку разделитель элементов по умолчанию – ', ', вывод может содержать завершающие пробелы, когда указан indent. Чтобы избежать этого, можно использовать separators=(',', ': ').

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

encoding – это кодировка символов для экземпляров str, по умолчанию UTF-8.

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

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

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

Примечание

В отличие от 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, encoding="utf-8", default=None, sort_keys=False, **kw)

Сериализует obj в str в формате JSON, используя таблицу преобразования. Если ensure_ascii равен false, результат может содержать не-ASCII символы, и возвращаемое значение может быть экземпляром unicode.

Аргументы имеют тот же смысл, что и в dump().

Примечание

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

json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Десериализует fp (поддерживающий .read() файлоподобный объект содержащий документ JSON) в объект Python с помощью таблицы преобразования.

Если содержимое fp закодировано с помощью кодировки на основе ASCII, отличной от UTF-8 (например, latin-1), то необходимо указать соответствующее имя encoding. Кодировки, не основанные на ASCII (такие как UCS-2), не допускаются; их следует обернуть с помощью codecs.getreader(encoding)(fp) или просто декодировать в объект unicode и передать в loads().

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

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

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

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

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

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

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

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

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Десериализует s (экземпляр str или unicode, содержащий JSON-документ) в объект Python с использованием таблицы преобразования.

Если s является экземпляром str и закодирован с помощью кодировки на основе ASCII, отличной от UTF-8 (например, latin-1), то необходимо указать соответствующее имя encoding. Кодировки, не основанные на ASCII (такие как UCS-2), не допускаются; их следует сначала декодировать в unicode.

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

18.2.2. Кодировщики и декодировщикиEncoders and Decoders

class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

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

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

JSON

Python

объект

dict

массив

список

строка

unicode

число (int)

int, long

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

float

истина

True

ложь

False

null

None

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

encoding определяет кодировку, используемую для интерпретации любых объектов str, декодированных этим экземпляром (по умолчанию UTF-8). Не влияет на декодирование объектов unicode.

Обратите внимание, что в настоящее время работают только кодировки, являющиеся надмножеством ASCII; строки других кодировок следует передавать в виде unicode.

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

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

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

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

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

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

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

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

decode(s)

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

raw_decode(s)

Декодирует документ JSON из s (str или unicode, начинающийся с документа JSON) и возвращает кортеж из двух элементов: представление в виде объекта Python и индекс в s, на котором документ закончился.

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

class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])

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

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

Python

JSON

dict

объект

list, tuple

массив

str, unicode

строка

int, long, float

число

True

истина

False

ложь

None

null

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

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

Если ensure_ascii равно true (по умолчанию), все не-ASCII символы в выводе экранируются последовательностями \uXXXX, и результатом являются экземпляры str, состоящие только из ASCII-символов. Если ensure_ascii равно false, результат может быть экземпляром unicode. Обычно это происходит, если входные данные содержат строки unicode или используется параметр encoding.

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

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

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

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

Примечание

Поскольку разделителем элементов по умолчанию является ', ', при указании indent в выводе могут появляться концевые пробелы. Чтобы избежать этого, можно использовать separators=(',', ': ').

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

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

Если encoding не равно None, то все входные строки перед кодированием в JSON будут преобразованы в unicode с использованием этой кодировки. По умолчанию используется UTF-8.

default(o)

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

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

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   # Пусть метод базового класса по умолчанию возбуждает TypeError
   return JSONEncoder.default(self, o)
encode(o)

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

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

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

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

18.2.3. Соответствие стандартам и интероперабельностьStandard Compliance and Interoperability

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

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

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

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

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

18.2.3.1. Кодировки символовCharacter Encodings

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

Десериализатор этого модуля напрямую работает только с кодировками, совместимыми с ASCII; UTF-16, UTF-32 и другие несовместимые с ASCII кодировки требуют применения обходных путей, описанных в документации к параметру encoding десериализатора.

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

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

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

18.2.3.2. Бесконечные и NaN значения чиселInfinite and NaN Number Values

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

>>> # Ни один из этих вызовов не возбуждает исключение, но результаты не являются корректным JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # То же самое при десериализации
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan

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

18.2.3.3. Повторяющиеся имена внутри объектаRepeated Names Within an Object

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

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

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

18.2.3.4. Значения верхнего уровня, не являющиеся объектом или массивомTop-level Non-Object, Non-Array Values

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

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

18.2.3.5. Ограничения реализацииImplementation Limitations

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

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

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

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

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

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

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

Сноски

1

Как отмечено в списке ошибок RFC 7159, JSON допускает символы U+2028 (LINE SEPARATOR) и U+2029 (PARAGRAPH SEPARATOR) в строках, тогда как JavaScript (начиная с ECMAScript Edition 5.1) – нет.