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({'6': 7, '4': 5}, sort_keys=True, indent=4))
{
"4": 5,
"6": 7
}
Специализация кодирования объектов JSON:
>>> import json
>>> def custom_json(obj):
... if isinstance(obj, complex):
... return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
... raise TypeError(f'Cannot serialize object of {type(obj)}')
...
>>> json.dumps(1 + 2j, default=custom_json)
'{"__complex__": true, "real": 1.0, "imag": 2.0}'
Декодирование 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 super().default(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()
), используя этот conversion table.Если значение 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
), то будет использоватьсяValueError
для сериализации значений вне диапазонаfloat
(nan
,inf
,-inf
) в строгом соответствии со спецификацией JSON. Если значение allow_nan равно true, то будут использоваться их эквиваленты в JavaScript (NaN
,Infinity
,-Infinity
).Если indent - неотрицательное целое число или строка, то элементы массива JSON и члены объекта будут напечатаны с этим уровнем отступа. Уровень отступа, равный 0, отрицательный или
""
, будет вставлять только новые строки.None
(по умолчанию) выбирает наиболее компактное представление. При использовании целого положительного числа отступ составляет столько-то пробелов на уровень. Если indent - это строка (например,"\t"
), то эта строка используется для отступа каждого уровня.Изменено в версии 3.2: Разрешите использовать строки для indent в дополнение к целым числам.
Если указано, разделители должны быть кортежем
(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: Все необязательные параметры теперь имеют значение keyword-only.
- 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
с помощью этого conversion table. Аргументы имеют то же значение, что и в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()
-поддерживающий text file или binary file, содержащий JSON-документ) в объект Python с помощью этого conversion table.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, который нужно декодировать. По умолчанию это эквивалентно
float(num_str)
. Это может быть использовано для использования другого типа данных или парсера для JSON float (например,decimal.Decimal
).parse_int, если указано, будет вызываться со строкой каждого JSON int, который нужно декодировать. По умолчанию это эквивалентно
int(num_str)
. Это может быть использовано для использования другого типа данных или парсера для целых чисел JSON (например,float
).Изменено в версии 3.11: Значение по умолчанию parse_int
int()
теперь ограничивает максимальную длину целочисленной строки через integer string conversion length limitation интерпретатора, что помогает избежать атак типа «отказ в обслуживании».parse_constant, если указан, будет вызван с одной из следующих строк:
'-Infinity'
,'Infinity'
,'NaN'
. Это можно использовать для того, чтобы вызвать исключение, если встречаются недопустимые числа JSON.Изменено в версии 3.1: parse_constant больше не вызывается для „null“, „true“, „false“.
Чтобы использовать собственный подкласс
JSONDecoder
, укажите его с помощью ключевого словаcls
; в противном случае используетсяJSONDecoder
. Дополнительные аргументы ключевого слова будут переданы в конструктор класса.Если десериализуемые данные не являются корректным JSON-документом, будет выдано сообщение
JSONDecodeError
.Изменено в версии 3.6: Все необязательные параметры теперь имеют значение keyword-only.
Изменено в версии 3.6: fp теперь может быть binary file. Входная кодировка должна быть 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 с помощью этого conversion table.Остальные аргументы имеют то же значение, что и в
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
объект
диктант
массив
список
строка
str
число (int)
int
число (вещественное)
float
правда
Правда
ложь
Ложь
null
Нет
Он также понимает
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, который нужно декодировать. По умолчанию это эквивалентно
float(num_str)
. Это может быть использовано для использования другого типа данных или парсера для JSON float (например,decimal.Decimal
).parse_int, если указано, будет вызываться со строкой каждого JSON int, который нужно декодировать. По умолчанию это эквивалентно
int(num_str)
. Это может быть использовано для использования другого типа данных или парсера для целых чисел JSON (например,float
).parse_constant, если указан, будет вызван с одной из следующих строк:
'-Infinity'
,'Infinity'
,'NaN'
. Это можно использовать для того, чтобы вызвать исключение, если встречаются недопустимые числа JSON.Если значение strict равно false (по умолчанию``True``), то в строках будут разрешены управляющие символы. Управляющие символы в данном контексте - это символы с кодами в диапазоне 0–31, включая
'\t'
(табуляция),'\n'
,'\r'
и'\0'
.Если десериализуемые данные не являются корректным JSON-документом, будет выдано сообщение
JSONDecodeError
.Изменено в версии 3.6: Все параметры теперь равны keyword-only.
- decode(s)¶
Возвращает Python-представление s (экземпляр
str
, содержащий JSON-документ).JSONDecodeError
будет поднята, если данный 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
диктант
объект
список, кортеж
массив
str
строка
int, float, int- и float-производные Enums
номер
Правда
правда
Ложь
ложь
Нет
null
Изменено в версии 3.4: Добавлена поддержка классов Enum, производных от int и float.
Чтобы расширить эту функцию для распознавания других объектов, создайте подкласс и реализуйте метод
default()
с другим методом, который возвращает сериализуемый объект дляo
, если это возможно, иначе он должен вызывать реализацию суперкласса (чтобы поднятьTypeError
).Если skipkeys равно false (по умолчанию), то при попытке закодировать ключи, которые не являются
str
,int
,float
илиNone
, будет возникать ошибкаTypeError
. Если значение 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 - это строка (например,"\t"
), то эта строка используется для отступа каждого уровня.Изменено в версии 3.2: Разрешите использовать строки для indent в дополнение к целым числам.
Если указано, разделители должны быть кортежем
(item_separator, key_separator)
. По умолчанию используется значение(', ', ': ')
, если indent равенNone
, и(',', ': ')
в противном случае. Для получения наиболее компактного представления JSON следует указать(',', ':')
, чтобы исключить пробельные символы.Изменено в версии 3.4: Используйте
(',', ': ')
по умолчанию, если значение indent не равноNone
.Если указано, default должна быть функцией, которая вызывается для объектов, которые не могут быть сериализованы иным способом. Она должна возвращать JSON-кодируемую версию объекта или вызывать сообщение
TypeError
. Если не указано, будет вызванаTypeError
.Изменено в версии 3.6: Все параметры теперь равны keyword-only.
- 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 super().default(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.
Added in version 3.5.
Соответствие стандартам и совместимость¶
Формат JSON задается символами RFC 7159 и ECMA-404. В этом разделе подробно описывается уровень соответствия данного модуля RFC. Для простоты подклассы JSONEncoder
и JSONDecoder
, а также параметры, кроме явно указанных, не рассматриваются.
Этот модуль не соответствует RFC в строгом смысле, реализуя некоторые расширения, которые являются допустимыми JavaScript, но не являются допустимыми JSON. В частности:
Принимаются и выводятся значения бесконечных чисел и NaN;
Повторяющиеся имена внутри объекта принимаются, и используется только значение последней пары имя-значение.
Поскольку RFC разрешает RFC-совместимым парсерам принимать входные тексты, которые не являются RFC-совместимыми, десериализатор этого модуля технически является RFC-совместимым при настройках по умолчанию.
Кодировки символов¶
RFC требует, чтобы JSON был представлен с использованием UTF-8, UTF-16 или UTF-32, при этом UTF-8 рекомендуется по умолчанию для максимальной совместимости.
Как разрешено, хотя и не требуется RFC, сериализатор этого модуля по умолчанию устанавливает ensure_ascii=True, тем самым экранируя вывод так, чтобы результирующие строки содержали только символы ASCII.
За исключением параметра ensure_ascii, этот модуль определен строго с точки зрения преобразования между объектами Python и Unicode strings
, и поэтому не затрагивает напрямую вопрос о кодировках символов.
RFC запрещает добавлять метку порядка байтов (BOM) в начало текста JSON, и сериализатор этого модуля не добавляет BOM в свой вывод. RFC разрешает, но не требует, чтобы десериализаторы JSON игнорировали начальный BOM на своем входе. Десериализатор этого модуля выдает ошибку ValueError
, если начальный BOM присутствует.
RFC не запрещает в явном виде строки JSON, содержащие последовательности байтов, которые не соответствуют действительным символам Юникода (например, непарные суррогаты UTF-16), но отмечает, что они могут вызвать проблемы с совместимостью. По умолчанию этот модуль принимает и выводит (при наличии в исходном str
) кодовые точки для таких последовательностей.
Бесконечные и NaN-значения чисел¶
RFC не разрешает представлять бесконечные или NaN-значения чисел. Несмотря на это, по умолчанию модуль принимает и выводит Infinity
, -Infinity
и NaN
так, как если бы они были допустимыми значениями литерала числа JSON:
>>> # Neither of these calls raises an exception, but the results are not valid JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # Same when deserializing
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan
В сериализаторе для изменения этого поведения можно использовать параметр allow_nan. В десериализаторе для изменения этого поведения можно использовать параметр parse_constant.
Повторяющиеся имена внутри объекта¶
RFC определяет, что имена внутри JSON-объекта должны быть уникальными, но не указывает, как следует обрабатывать повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не вызывает исключения; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
Параметр object_pairs_hook может быть использован для изменения этого поведения.
Значения верхнего уровня, не относящиеся к объектам и массивам¶
Старая версия JSON, указанная в устаревшем RFC 4627, требовала, чтобы значение верхнего уровня текста JSON было либо объектом JSON, либо массивом (Python dict
или list
) и не могло быть значением JSON null, boolean, number или string. В 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¶
Сортировка вывода словарей в алфавитном порядке по ключу.
Added in version 3.5.
- --no-ensure-ascii¶
Отключите экранирование неасквидных символов, см. дополнительную информацию в разделе
json.dumps()
.Added in version 3.9.
- --json-lines¶
Разберите каждую строку ввода как отдельный JSON-объект.
Added in version 3.8.
- --indent, --tab, --no-indent, --compact¶
Взаимоисключающие опции для контроля пробельных символов.
Added in version 3.9.
- -h, --help¶
Показать сообщение о помощи.
Сноски