Spec-Zone.ru › Python 3.11

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 – это строка (например, "\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 – это необязательная функция, которая будет вызываться с результатом любого декодированного объекта литерала (a 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.11: По умолчанию 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-документа) и возвращает кортеж из 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

словарь

объект

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

массив

строка

строка

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

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

Если указаны, separators должны быть кортежем из 2 элементов. По умолчанию это (', ', ': ') если 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. Этот раздел описывает уровень соответствия модуля данной спецификации. Для простоты, подклассы 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, числом или строковым значением. 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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/json.html

Spec-Zone.ru

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