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.
19.2.1. Основные примеры использования
-
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), то ключи словаря, которые не являются базовыми типами (str,int,float,bool,None) будут пропущены вместо того, чтобы подниматьTypeError.Модуль
jsonвсегда создаётstrобъекты, а неbytesобъекты. Следовательно,fp.write()должен поддерживатьstrв качестве входных данных.Если ensure_ascii истинно (по умолчанию), вывод гарантированно содержит все входящие не-ASCII символы, экранированные. Если ensure_ascii ложно, эти символы будут выведены как есть.
Если check_circular ложно (по умолчанию:
True), то проверка циклических ссылок для контейнеров будет пропущена, и циклическая ссылка приведёт кOverflowError(или хуже).Если allow_nan ложно (по умолчанию:
True), то сериализация значенийfloatвне диапазона (nan,inf,-inf) приведёт кValueErrorв строгом соответствии со спецификацией JSON. Если allow_nan истинно, будут использованы их 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 истинно (по умолчанию:
False), то выходные данные словарей будут отсортированы по ключам.Для использования подкласса
JSONEncoder(например, для переопределения методаdefault()для сериализации дополнительных типов), укажите его с аргументом cls; в противном случае используетсяJSONEncoder.Изменено в версии 3.6: Все необязательные параметры теперь только ключевые.
-
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 в
strформате JSON с использованием этой таблицы преобразования. Аргументы имеют то же значение, что и в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 (a
.read()-совместимый текстовый файл или бинарный файл содержащий JSON-документ) в объект Python, используя эту таблицу преобразования.object_hook — это необязательная функция, которая будет вызвана с результатом любого объекта, декодированного из литерала (a
dict). Возвращаемое значение object_hook будет использоваться вместоdict. Эта функция может быть использована для реализации пользовательских декодеров (например, JSON-RPC с указанием класса).object_pairs_hook — это необязательная функция, которая будет вызвана с результатом любого объекта, декодированного из литерала с упорядоченным списком пар. Возвращаемое значение object_pairs_hook будет использоваться вместо
dict. Эта функция может быть использована для реализации пользовательских декодеров, которые зависят от порядка декодирования пар ключ-значение (например,collections.OrderedDict()запомнит порядок вставки). Если определена 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-числа.Изменено в версии 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, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) -
Десериализуйте s (a
str,bytesилиbytearrayэкземпляр, содержащий JSON-документ) в объект Python, используя эту таблицу преобразования.Другие аргументы имеют то же значение, что и в
load(), за исключением encoding, который игнорируется и устарел.Если данные, которые десериализуются, не являются допустимым JSON-документом, будет вызвано
JSONDecodeError.
19.2.2. Кодировщики и декодировщики
-
class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None) -
Простой декодер JSON.
По умолчанию, при декодировании выполняет следующие преобразования:
JSON
Python
объект
dict
массив
list
строка
str
число (целое)
int
число (вещественное)
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. Эта функция может быть использована для реализации пользовательских декодеров, которые зависят от порядка декодирования пар ключ-значение (например,collections.OrderedDict()запомнит порядок вставки). Если 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 ложно (
True— значение по умолчанию), тогда управляющие символы будут разрешены внутри строк. Управляющие символы в данном контексте — это те, у которых коды символов в диапазоне 0–31, включая'\t'(табуляция),'\n','\r'и'\0'.Если данные, которые десериализуются, не являются допустимым JSON-документом, будет вызвано
JSONDecodeError.Изменено в версии 3.6: Все параметры теперь являются только ключевыми.
-
decode(s) -
Возвращает представление Python из s (экземпляр
strсодержащий JSON-документ).Будет вызвано
JSONDecodeError, если предоставленный JSON-документ некорректен.
-
raw_decode(s) -
Декодирует JSON-документ из s (a
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
dict
объект
list, tuple
массив
str
строка
int, float, int- и float-производные перечисления
число
True
true
False
false
None
null
Изменено в версии 3.4: Добавлена поддержка int- и float-производных классов перечислений.
Чтобы расширить это для распознавания других объектов, создайте подкласс и реализуйте метод
default(), содержащий другой метод, возвращающий сериализуемый объект дляo, если возможно, в противном случае он должен вызвать реализацию суперкласса (чтобы вызватьTypeError).Если skipkeys ложно (по умолчанию), то попытка кодирования ключей, которые не являются
str,int,floatилиNone, вызываетTypeError. Если 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).Например, чтобы поддержать произвольные итераторы, вы могли бы реализовать 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)
-
19.2.3. Исключения
-
exception json.JSONDecodeError(msg, doc, pos) -
Подкласс
ValueErrorсо следующими дополнительными атрибутами:-
msg -
Неформатированное сообщение об ошибке.
-
doc -
Документ JSON, который анализируется.
-
pos -
Начальный индекс doc, где произошел сбой анализа.
-
lineno -
Строка, соответствующая pos.
-
colno -
Столбец, соответствующий pos.
Добавлена в версии 3.5.
-
19.2.4. Соответствие стандарту и межсетевое взаимодействие
Формат JSON определен в RFC 7159 и в ECMA-404. В этом разделе подробно описано соответствие модуля данному стандарту. Для простоты JSONEncoder и JSONDecoder подклассы, а также параметры, отличные от явно указанных, не рассматриваются.
Этот модуль не строго соответствует RFC, реализуя некоторые расширения, которые действительны для JavaScript, но не для JSON. В частности:
- Бесконечные и NaN числовые значения принимаются и выводятся;
- Повторные имена в объекте принимаются, и используется только значение последней пары имя-значение.
Поскольку RFC допускает, что RFC-совместимые парсеры принимают тексты, которые не соответствуют RFC, десериализатор этого модуля технически RFC-совместим при стандартных настройках.
19.2.4.1. Кодировки символов
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) кодовые точки для таких последовательностей.
19.2.4.2. Бесконечные и 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 можно использовать для изменения этого поведения.
19.2.4.3. Повторные имена в объекте
RFC определяет, что имена в JSON-объекте должны быть уникальными, но не предписывает, как должны обрабатываться повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не генерирует исключение; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
Параметр object_pairs_hook можно использовать для изменения этого поведения.
19.2.4.4. Значения верхнего уровня, не являющиеся объектами и не являющиеся массивами
Предыдущая версия JSON, определённая устаревшей RFC 4627, требовала, чтобы значение верхнего уровня текста JSON было либо JSON объектом, либо массивом (Python dict или list), и не могло быть JSON null, boolean, числом или строковым значением. RFC 7159 убрало это ограничение, и этот модуль не и никогда не реализовывал это ограничение ни в своём сериализаторе, ни в своём десериализаторе.
Независимо от этого, для максимальной совместимости, вы можете добровольно придерживаться этого ограничения.
19.2.4.5. Ограничения реализации
Некоторые реализации JSON десериализаторов могут устанавливать ограничения на:
- размер принимаемых текстов JSON
- максимальный уровень вложенности JSON объектов и массивов
- диапазон и точность JSON чисел
- содержимое и максимальную длину JSON строк
Этот модуль не накладывает никаких таких ограничений, кроме тех, что установлены соответствующими типами данных Python самими по себе или самим интерпретатором Python.
При сериализации в JSON, будьте осторожны с такими ограничениями в приложениях, которые могут потреблять ваш JSON. В частности, часто JSON числа десериализуются в числа двойной точности IEEE 754 и, таким образом, подвержены ограничениям диапазона и точности этой системы представления. Это особенно важно при сериализации значений Python int с чрезвычайно большой величиной или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal.
19.2.5. Интерфейс командной строки
Исходный код: 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, чтобы отсортировать вывод словарей по ключам в алфавитном порядке.
19.2.5.1. Опции командной строки
-
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.
-
-h, --help -
Показать сообщение справки.
Примечания
-
1 -
Как отмечено в справочнике по ошибочным исправлениям RFC 7159, JSON допускает литерные символы U+2028 (РАЗДЕЛИТЕЛЬ СТРОК) и U+2029 (РАЗДЕЛИТЕЛЬ АБЗАЦОВ) в строках, тогда как JavaScript (по состоянию на ECMAScript издание 5.1) — нет.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/json.html