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

Исходный код: Lib/json/__init__.py.


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('\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({'4': 5, '6': 7}, sort_keys=True, indent=4))
{
    "4": 5,
    "6": 7
}

Декодирование 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 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 -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() file-like object) с помощью этого 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).

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 документа) и возвращает кортеж из 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 (по умолчанию), то при попытке кодировать ключи, которые не являются TypeError, str, int или float, будет возникать ошибка None. Если skipkeys равно true, то такие элементы просто пропускаются.

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

Если check_circular равно true (по умолчанию), то списки, dicts и пользовательские кодированные объекты будут проверяться на наличие круговых ссылок во время кодирования, чтобы предотвратить бесконечную рекурсию (которая приведет к появлению 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 json.JSONEncoder.default(self, 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.

Добавлено в версии 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, содержащие последовательности байтов, которые не соответствуют действительным символам Unicode (например, непарные суррогаты 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

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

Добавлено в версии 3.5.

--no-ensure-ascii

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

Добавлено в версии 3.9.

--json-lines

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

Добавлено в версии 3.8.

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

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

Добавлено в версии 3.9.

-h, --help

Показать справочное сообщение.

Сноски

1

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

Вернуться на верх