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


JSON (Объектная нотация JavaScript), определяется 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]
...         # Позволить методу базового класса по умолчанию вызвать 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 создан настройками этого модуля по умолчанию (в частности, значением по умолчанию разделителей), также является подмножеством YAML 1.0 и 1.1. Таким образом, данный модуль также можно использовать как YAML сериализатор.

Примечание

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

До Python 3.7 порядок dict не гарантировался, поэтому входные и выходные данные обычно скремблировались, если collections.OrderedDict не запрашивался специально. Начиная с Python 3.7, обычный dict стал сохранять порядок, поэтому больше не нужно указывать collections.OrderedDict для генерации и парсинга JSON.

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

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 истинно (по умолчанию: False), то ключи dict, которые не относятся к базовому типу (str, int, float, bool, None), будут пропущены вместо поднятия TypeError.

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

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

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

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

Чтобы использовать собственный подкласс JSONEncoder (например, тот, который переопределяет метод default() для сериализации дополнительных типов), укажите его с помощью cls kwarg; в противном случае используется 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, подлежащего декодированию. По умолчанию это эквивалент int(num_str). Это можно использовать для использования другого типа данных или парсера для целых чисел JSON (например, float).

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

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

Чтобы использовать собственный подкласс JSONDecoder, укажите его с помощью cls kwarg; в противном случае используется 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(), за исключением encoding, который игнорируется и считается устаревшим, начиная с Python 3.1.

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

Устарело с версии 3.1, будет удалено в 3.9 версии.: encoding ключевой аргумент.

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

Кодеры и декодеры

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

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

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

JSON Python
object dict
array list
string str
number (int) int
number (real) float
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, подлежащего декодированию. По умолчанию это эквивалент int(num_str). Это можно использовать для использования другого типа данных или парсера для целых чисел JSON (например, float).

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

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

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

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

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
dict object
list, tuple array
str string
int, float, int- & float-derived Enums number
True true
False false
None null

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

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

Если skipkeys ложно (по умолчанию), то это TypeError для попытки кодирования ключей, которые не являются str, int, float или None. Если skipkeys истинно, такие элементы просто пропускаются.

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

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

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

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

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

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

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

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

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

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

default(o)

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

Например, для поддержки произвольных итераторов вы можете реализовать по умолчанию вот так:

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   # Пусть базовый класс по умолчанию метод поднимает 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 игнорировали исходную спецификацию во входных данных. Десериализатор этого модуля поднимает ValueError, когда присутствует начальный BOM.

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

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

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.

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

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, логическим, числом или строковым значением. RFC 7159 снял это ограничение, и этот модуль не применяет и никогда не реализовывал это ограничение ни в сериализаторе, ни в десериализаторе.

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

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

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

  • размер принимаемых текстов JSON
  • максимальный уровень вложенности объектов и массивов JSON
  • диапазон и точность чисел JSON
  • содержимое и максимальная длину строк JSON

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

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

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


Модуль 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": "А Теперь о Чем-То Совершенно Другом",
        "year": 1971
    },
    {
        "title": "Монти Пайтон и Святой Грааль",
        "year": 1975
    }
]

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

outfile

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

--sort-keys

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

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

--json-lines

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

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

-h, --help

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

Сноски

[1]Как отмечено в исправления для RFC 7159, JSON допускает использование литералов U+2028 (LINE SEPARATOR) и U+2029 (PARAGRAPH SEPARATOR) символов в строках, то время как JavaScript (начиная с ECMAScript Edition 5.1) — нет.