Spec-Zone.ru › Python 3.9

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({'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() объект, подобный файлу) с помощью этой таблицы преобразований.

Если 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), то сериализация значений float вне диапазона (nan, inf, -inf) будет вызывать ValueError в строгом соответствии со спецификацией JSON. Если allow_nan равно true, будут использоваться их JavaScript-эквиваленты (NaN, Infinity, -Infinity).

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

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

Если указано, separators должно быть кортежем (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: Все необязательные параметры теперь являются только ключевыми.

Примечание

В отличие от 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 с использованием этой таблицы преобразований. Аргументы имеют то же значение, что и в 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() текстовый файл или бинарный файл содержащий JSON-документ) в объект Python, используя эту таблицу преобразований.

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(num_str). Это можно использовать для использования другого типа данных или парсера для чисел с плавающей запятой JSON (например, decimal.Decimal).

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

Изменено в версии 3.9.14: По умолчанию parse_int функции int() теперь ограничивает максимальную длину строки целого числа с помощью ограничения интерпретатора ограничения длины строк целых чисел для предотвращения атак типа «отказ в обслуживании».

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

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

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

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

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

Изменено в версии 3.6: fp теперь может быть бинарным файлом. Кодировка ввода должна быть 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 с использованием этой таблицы преобразования.

Другие аргументы имеют то же значение, что и в 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

объект

словарь

массив

список

строка

строка

число (целое)

целое число

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

число с плавающей точкой

true

True

false

False

null

None

Он также понимает 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(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-документом, будет вызвано исключение JSONDecodeError.

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

decode(s)

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

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

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

словарь

объект

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

массив

строка

строка

целое число, число с плавающей точкой, целые и вещественные Enum

число

True

true

False

false

None

null

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

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

Если skipkeys имеет значение false (по умолчанию), будет вызвана ошибка TypeError при попытке закодировать ключи, которые не являются str, int, float или None. Если 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-массива и члены JSON-объекта будут отформатированы с указанным уровнем отступа. Уровень отступа 0, отрицательное число или "" будут вставлять только переводы строк. None (по умолчанию) выбирает самое компактное представление. Использование положительного целого числа в качестве отступа вставляет столько пробелов на каждый уровень. Если indent — строка (например, "\t"), эта строка используется для отступа каждого уровня.

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

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

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

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

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

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

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

Введено в версии 3.9.

--json-lines

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

Введено в версии 3.8.

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

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

Введено в версии 3.9.

-h, --help

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

Примечания

1

Как отмечено в справочнике по ошибкам RFC 7159, JSON допускает символы U+2028 (РАЗДЕЛИТЕЛЬ СТРОК) и U+2029 (РАЗДЕЛИТЕЛЬ АБЗАЦОВ) в строках, тогда как JavaScript (по состоянию на ECMAScript Edition 5.1) — нет.

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/json.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API