json — Кодировщик и декодировщик JSON
Исходный код: Lib/json/__init__.py
JSON (JavaScript Object Notation), определённый в RFC 7159 (который устаревает RFC 4627) и ECMA-404, представляет собой лёгкий формат обмена данными, вдохновлённый синтаксисом литералов объектов JavaScript ([1]). Он не является строгим подмножеством синтаксиса JavaScript.
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 из командной строки для валидации и красивого вывода JSON:
$ 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.
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 равно 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), проверка циклических ссылок для контейнерных типов будет пропущена, и циклическая ссылка приведёт кOverflowError(или хуже).Если allow_nan равно false (по умолчанию:
True), то будетValueErrorпри сериализации значенийfloatвне диапазона (nan,inf,-inf) в строгом соответствии со спецификацией JSON. Если allow_nan равно true, будут использоваться их JavaScript эквиваленты (NaN,Infinity,-Infinity)Если indent является неотрицательным целым числом или строкой, элементы массива JSON и члены объекта будут красиво отформатированы с таким уровнем отступа. Уровень отступа 0, отрицательный или
""будут вставлять только новые строки.None(значение по умолчанию) выбирает наиболее компактное представление. Использование положительного целого числа indent вставляет отступы в виде соответствующего количества пробелов на каждом уровне. Если indent является строкой (такой как"\t"), эта строка используется для отступа каждого уровня.Изменено в версии 3.2: Допускается использование строк для indent в дополнение к целым числам.
Если указано, separators должно быть кортежем из
(item_separator, key_separator). По умолчанию это(', ', ': ')если indentNoneи(',', ': ')в противном случае. Для получения наиболее компактного представления JSON следует указать(',', ':')для удаления пробелов.Изменено в версии 3.4: По умолчанию используется
(',', ': ')если indent неNone.Если указано, default должна быть функцией, которая вызывается для объектов, которые нельзя сериализовать. Она должна вернуть JSON-кодируемую версию объекта или повысить
TypeError. Если не указано, то будет повышеноTypeError.Если sort_keys равно true (по умолчанию:
False), то вывод словарей будет отсортирован по ключу.Для использования пользовательского подкласса
JSONEncoder(например, подкласса, переопределяющего методdefault()для сериализации дополнительных типов), укажите его с параметром cls; в противном случае используетсяJSONEncoder.
-
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().Примечание
В отличие от
pickleиmarshal, JSON не является протоколом с фреймами, поэтому попытка сериализовать несколько объектов с помощью повторяющихся вызововdump()с одним и тем же fp приведёт к созданию некорректного файла JSON.Примечание
Ключи в парах ключ/значение 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. Эта функция может быть использована для реализации пользовательских декодеров, которые полагаются на порядок декодирования пар ключ-значение (например,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.
-
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 (объект
str, содержащий JSON-документ) в объект Python, используя эту таблицу преобразования.Другие аргументы имеют такое же значение, как и в
load(), за исключением encoding, который игнорируется и устарел.Если данные, подлежащие десериализации, не являются допустимым JSON-документом, будет поднято исключение
JSONDecodeError.
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 объект словарь массив список строка строка число (целое) целое число число (вещественное) число с плавающей точкой true True false False null None Также понимает
NaN,Infinity, и-Infinityв качестве соответствующихfloatзначений, что выходит за рамки спецификации JSON.Если указан object_hook, то он будет вызываться с результатом декодирования каждого JSON-объекта, а его возвращаемое значение будет использоваться вместо заданного
dict. Это можно использовать для предоставления пользовательских десериализаций (например, для поддержки JSON-RPC class hinting).Если указан 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.-
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 dict объект list, tuple массив str строка int, float, целые и вещественные перечисления число True true False false None null Изменено в версии 3.4: Добавлена поддержка целых и вещественных перечислений.
Для расширения поддержки других объектов, создайте подкласс и реализуйте метод
default()с другим методом, который возвращает сериализуемый объект дляo, если это возможно, в противном случае он должен вызвать реализацию базового класса (чтобы вызватьTypeError).Если skipkeys имеет значение false (по умолчанию), то попытка кодирования ключей, которые не являются
str,int,floatилиNone, являетсяTypeError. Если skipkeys имеет значение true, такие элементы просто пропускаются.Если ensure_ascii имеет значение true (по умолчанию), то в выходных данных гарантируется, что все не-ASCII символы экранированы. Если ensure_ascii имеет значение false, эти символы будут выведены как есть.
Если check_circular имеет значение true (по умолчанию), то списки, словари и пользовательские закодированные объекты будут проверены на циклические ссылки во время кодирования, чтобы предотвратить бесконечную рекурсию (что приведет к
OverflowError). В противном случае такая проверка не выполняется.Если allow_nan имеет значение true (по умолчанию), то
NaN,Infinity, и-Infinityбудут закодированы как есть. Это поведение не соответствует спецификации JSON, но согласуется с большинством JavaScript-кодировщиков и декодеров. В противном случае кодирование таких чисел с плавающей точкой приведет кValueError.Если sort_keys имеет значение true (по умолчанию:
False), то выходные данные словарей будут отсортированы по ключу; это полезно для регрессионных тестов, чтобы убедиться, что сериализации JSON можно сравнивать ежедневно.Если 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.-
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)
-
3. Исключение
-
exception json.JSONDecodeError(msg, doc, pos) -
Подкласс
ValueErrorс дополнительными атрибутами:-
msg -
Неформализованное сообщение об ошибке.
-
doc -
Документ JSON, который анализируется.
-
pos -
Начальный индекс doc, где произошел сбой анализа.
-
lineno -
Строка, соответствующая pos.
-
colno -
Столбец, соответствующий pos.
Добавлено в версии 3.5.
-
4. Соответствие стандартам и взаимозаменяемость
Формат JSON определен в RFC 7159 и ECMA-404. Этот раздел описывает уровень соответствия этого модуля RFC. Для простоты, подклассы JSONEncoder и JSONDecoder, а также параметры, кроме явно указанных, не рассматриваются.
Этот модуль не полностью соответствует RFC, реализуя некоторые расширения, которые являются допустимыми в JavaScript, но не допустимыми в JSON. В частности:
- Бесконечные и NaN числовые значения принимаются и выводятся;
- Повторяющиеся имена внутри объекта принимаются, и используется только значение последней пары имя-значение.
Поскольку RFC разрешает RFC-совместимым анализаторам принимать тексты ввода, которые не соответствуют RFC, десериализатор этого модуля технически соответствует RFC при значениях по умолчанию.
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-строки, содержащие последовательности байтов, которые не соответствуют допустимым Unicode-символам (например, неспаренные суррогаты UTF-16), но отмечает, что они могут вызывать проблемы с совместимостью. По умолчанию этот модуль принимает и выводит (при наличии в исходной str) коды символов для таких последовательностей.
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 можно использовать для изменения этого поведения.
4.3. Повторяющиеся имена внутри объекта
RFC определяет, что имена внутри JSON-объекта должны быть уникальными, но не предписывает, как должны обрабатываться повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не вызывает исключение; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
Параметр object_pairs_hook может использоваться для изменения этого поведения.
4.4. Значения верхнего уровня, не являющиеся объектами и массивами
Старая версия JSON, определённая устаревшей RFC 4627, требовала, чтобы значение верхнего уровня текста JSON должно было быть либо JSON-объектом, либо массивом (Python dict или list), и не могло быть значением JSON null, boolean, number или string. RFC 7159 удалила это ограничение, и этот модуль не реализовывал и никогда не реализовывал это ограничение ни в своём сериализаторе, ни в своём десериализаторе.
Несмотря на это, для максимальной совместимости вы можете добровольно придерживаться ограничения.
END_OF_DOCUMENT_MARKER4.5. Ограничения реализации
Некоторые реализации десериализатора JSON могут устанавливать ограничения на:
- размер принимаемых текстов JSON
- максимальный уровень вложенности объектов и массивов JSON
- диапазон и точность чисел JSON
- содержание и максимальную длину строк JSON
Этот модуль не накладывает никаких таких ограничений, кроме тех, которые установлены соответствующими типами данных Python или самим интерпретатором Python.
При сериализации в JSON будьте внимательны к таким ограничениям в приложениях, которые могут использовать ваш JSON. В частности, числа JSON обычно десериализуются в числа двойной точности IEEE 754 и, следовательно, подвержены ограничениям по диапазону и точности этого представления. Это особенно актуально при сериализации значений Python int чрезвычайно большой величины или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal.
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, чтобы отсортировать вывод словарей по ключам в алфавитном порядке.
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 Edition 5.1) этого не делает. |
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/json.html