Содержание страницы
18.2. json – кодировщик и декодировщик JSON¶json – JSON encoder and decoder
Новое в версии 2.6.
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(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO 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, separators=(',', ': '))
{
"4": 5,
"6": 7
}
Декодирование JSON:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'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 -mjson.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.
18.2.1. Основное использование¶Basic Usage
-
json.dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)¶ Сериализует obj в поток в формате JSON в fp (с поддержкой
.write()объекта, похожего на файл) с помощью этой таблицы преобразования.Если skipkeys равен true (по умолчанию:
False), то ключи словаря, которые не относятся к базовому типу (str,unicode,int,long,float,bool,None), будут пропущены вместо возбужденияTypeError.Если ensure_ascii равен true (по умолчанию), то все не-ASCII символы в выводе экранируются последовательностями
\uXXXX, и результатом является экземплярstr, состоящий только из символов ASCII. Если ensure_ascii равен false, некоторые блоки, записанные в fp, могут быть экземплярамиunicode. Обычно это происходит из-за того, что входные данные содержат строки unicode или используется параметр encoding. Если толькоfp.write()явно не понимаетunicode(как вcodecs.getwriter()), это, скорее всего, вызовет ошибку.Если 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. Чтобы избежать этого, можно использоватьseparators=(',', ': ').Если указан, separators должен быть кортежем
(item_separator, key_separator). По умолчанию используются(', ', ': '). Чтобы получить наиболее компактное представление JSON, следует указать(',', ':')для устранения пробелов.encoding – это кодировка символов для экземпляров str, по умолчанию UTF-8.
Если указан, 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, encoding="utf-8", default=None, sort_keys=False, **kw)¶ Сериализует obj в
strв формате JSON, используя таблицу преобразования. Если ensure_ascii равен false, результат может содержать не-ASCII символы, и возвращаемое значение может быть экземпляромunicode.Аргументы имеют тот же смысл, что и в
dump().Примечание
Ключи в парах ключ-значение JSON всегда имеют тип
str. При преобразовании словаря в JSON все его ключи приводятся к строкам. В результате, если словарь преобразовать в JSON, а затем обратно в словарь, полученный словарь может не совпадать с исходным. То естьloads(dumps(x)) != x, если x имеет нестроковые ключи.
-
json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])¶ Десериализует fp (поддерживающий
.read()файлоподобный объект содержащий документ JSON) в объект Python с помощью таблицы преобразования.Если содержимое fp закодировано с помощью кодировки на основе ASCII, отличной от UTF-8 (например, latin-1), то необходимо указать соответствующее имя encoding. Кодировки, не основанные на ASCII (такие как UCS-2), не допускаются; их следует обернуть с помощью
codecs.getreader(encoding)(fp)или просто декодировать в объектunicodeи передать вloads().object_hook – необязательная функция, которая будет вызвана с результатом декодирования любого литерала объекта (
dict). Возвращаемое значение object_hook будет использовано вместоdict. Эту возможность можно использовать для реализации пользовательских декодеров (например, JSON-RPC подсказки класса).object_pairs_hook – это необязательная функция, которая будет вызвана с результатом декодирования любого объектного литерала в виде упорядоченного списка пар. Возвращаемое значение object_pairs_hook будет использовано вместо
dict. Эту возможность можно использовать для реализации собственных декодеров, которые полагаются на порядок декодирования пар ключ-значение (например,collections.OrderedDict()запоминает порядок вставки). Если также определён object_hook, то object_pairs_hook имеет приоритет.Изменено в версии 2.7: Добавлена поддержка 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.Изменено в версии 2.7: parse_constant больше не вызывается для ‘null’, ‘true’, ‘false’.
Чтобы использовать пользовательский подкласс
JSONDecoder, укажите его с помощью именованного аргументаcls; в противном случае используетсяJSONDecoder. Дополнительные именованные аргументы будут переданы конструктору класса.
-
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])¶ Десериализует s (экземпляр
strилиunicode, содержащий JSON-документ) в объект Python с использованием таблицы преобразования.Если s является экземпляром
strи закодирован с помощью кодировки на основе ASCII, отличной от UTF-8 (например, latin-1), то необходимо указать соответствующее имя encoding. Кодировки, не основанные на ASCII (такие как UCS-2), не допускаются; их следует сначала декодировать вunicode.Остальные аргументы имеют тот же смысл, что и в
load().
18.2.2. Кодировщики и декодировщики¶Encoders and Decoders
-
class
json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])¶ Простой JSON-декодер.
По умолчанию выполняет следующие преобразования при декодировании:
JSON
Python
объект
dict
массив
список
строка
unicode
число (int)
int, long
число (вещественное)
float
истина
True
ложь
False
null
None
Также
NaN,Infinityи-Infinityраспознаются как соответствующие значенияfloat, что выходит за рамки спецификации JSON.encoding определяет кодировку, используемую для интерпретации любых объектов
str, декодированных этим экземпляром (по умолчанию UTF-8). Не влияет на декодирование объектовunicode.Обратите внимание, что в настоящее время работают только кодировки, являющиеся надмножеством ASCII; строки других кодировок следует передавать в виде
unicode.object_hook, если указан, будет вызываться с результатом декодирования каждого JSON объекта, и его возвращаемое значение будет использоваться вместо полученного
dict. Это может использоваться для предоставления пользовательской десериализации (например, для поддержки подсказок классов JSON-RPC).object_pairs_hook, если указан, будет вызван с результатом каждого JSON-объекта, декодированного в виде упорядоченного списка пар. Возвращаемое значение object_pairs_hook будет использовано вместо
dict. Эта возможность может быть использована для реализации собственных декодеров, которые полагаются на порядок декодирования пар ключ-значение (например,collections.OrderedDict()запоминает порядок вставки). Если object_hook также определён, то object_pairs_hook имеет приоритет.Изменено в версии 2.7: Добавлена поддержка object_pairs_hook.
parse_float, если указан, будет вызван со строкой каждого декодируемого JSON-числа с плавающей запятой. По умолчанию это эквивалентно
float(num_str). Это может быть использовано для использования другого типа данных или парсера для JSON-чисел с плавающей запятой (например,decimal.Decimal).parse_int, если указан, будет вызван со строкой каждого декодируемого JSON-целого числа. По умолчанию это эквивалентно
int(num_str). Это может быть использовано для использования другого типа данных или парсера для JSON-целых чисел (например,float).parse_constant, если указан, будет вызван с одной из следующих строк:
'-Infinity','Infinity','NaN'. Это может быть использовано для генерации исключения при обнаружении некорректных чисел JSON.Если strict равно false (по умолчанию
True), то управляющие символы допускаются внутри строк. Под управляющими символами здесь понимаются символы с кодами в диапазоне 0–31, включая'\t'(табуляция),'\n','\r'и'\0'.Если десериализуемые данные не являются корректным JSON-документом, будет вызвано
ValueError.-
decode(s)¶ Возвращает представление в виде объекта Python для s (экземпляра
strилиunicode, содержащего документ JSON).
-
raw_decode(s)¶ Декодирует документ JSON из s (
strилиunicode, начинающийся с документа JSON) и возвращает кортеж из двух элементов: представление в виде объекта Python и индекс в s, на котором документ закончился.Это можно использовать для декодирования JSON-документа из строки, в конце которой могут быть лишние данные.
-
-
class
json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])¶ Расширяемый JSON-кодировщик для структур данных Python.
По умолчанию поддерживает следующие объекты и типы:
Python
JSON
dict
объект
list, tuple
массив
str, unicode
строка
int, long, float
число
True
истина
False
ложь
None
null
Чтобы расширить функциональность на другие объекты, создайте подкласс и реализуйте метод
default()с другим методом, который возвращает сериализуемый объект дляo, если это возможно; в противном случае следует вызвать реализацию суперкласса (для возбужденияTypeError).Если skipkeys имеет значение false (по умолчанию), то попытка кодировать ключи, не являющиеся str, int, long, float или
None, приведёт кTypeError. Если skipkeys равно true, такие элементы просто пропускаются.Если ensure_ascii равно true (по умолчанию), все не-ASCII символы в выводе экранируются последовательностями
\uXXXX, и результатом являются экземплярыstr, состоящие только из ASCII-символов. Если ensure_ascii равно false, результат может быть экземпляромunicode. Обычно это происходит, если входные данные содержат строки unicode или используется параметр encoding.Если check_circular равен true (по умолчанию), то списки, словари и пользовательские закодированные объекты проверяются на наличие циклических ссылок во время кодирования, чтобы предотвратить бесконечную рекурсию (которая привела бы к
OverflowError). В противном случае такая проверка не выполняется.Если allow_nan равно true (по умолчанию), то значения
NaN,Infinityи-Infinityкодируются как есть. Такое поведение не соответствует спецификации JSON, но согласуется с большинством кодировщиков и декодировщиков на JavaScript. В противном случае при кодировании таких чисел с плавающей запятой возбуждаетсяValueError.Если sort_keys равно true (по умолчанию
False), то вывод словарей сортируется по ключам; это полезно для регрессионных тестов, чтобы обеспечить возможность сравнения JSON-сериализаций день ото дня.Если indent – неотрицательное целое число (по умолчанию
None), то элементы массивов JSON и члены объектов будут выводиться с красивым форматированием с указанным отступом. Уровень отступа 0 вставляет только символы новой строки.None– наиболее компактное представление.Примечание
Поскольку разделителем элементов по умолчанию является
', ', при указании indent в выводе могут появляться концевые пробелы. Чтобы избежать этого, можно использоватьseparators=(',', ': ').Если указан, separators должен быть кортежем
(item_separator, key_separator). По умолчанию используются(', ', ': '). Чтобы получить наиболее компактное представление JSON, следует указать(',', ':')для устранения пробелов.Если указан, default должен быть функцией, которая вызывается для объектов, которые не могут быть сериализованы иным способом. Она должна возвращать версию объекта, пригодную для JSON-кодирования, или возбуждать
TypeError. Если не указано, возбуждаетсяTypeError.Если encoding не равно
None, то все входные строки перед кодированием в JSON будут преобразованы в unicode с использованием этой кодировки. По умолчанию используется UTF-8.-
default(o)¶ В подклассе этот метод должен возвращать сериализуемый объект для o или вызывать базовую реализацию (для возбуждения
TypeError).Например, чтобы поддерживать произвольные итераторы, можно реализовать default следующим образом:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Пусть метод базового класса по умолчанию возбуждает TypeError return JSONEncoder.default(self, o)
-
encode(o)¶ Возвращает строковое представление структуры данных Python в формате JSON, o. Например:
>>> JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
-
iterencode(o)¶ Кодирует заданный объект o и выдаёт каждое строковое представление по мере готовности. Например:
for chunk in JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
-
18.2.3. Соответствие стандартам и интероперабельность¶Standard Compliance and Interoperability
Формат JSON определяется RFC 7159 и ECMA-404.
В этом разделе подробно описывается степень соответствия модуля RFC.
Для простоты JSONEncoder и JSONDecoder подклассы, а также параметры, не указанные явно, не рассматриваются.
Этот модуль не полностью соответствует RFC, реализуя некоторые расширения, которые являются допустимым JavaScript, но недопустимым JSON. В частности:
Бесконечные и NaN числовые значения принимаются и выводятся;
Повторяющиеся имена в объекте принимаются, и используется только значение последней пары.
Поскольку RFC разрешает совместимым с RFC анализаторам принимать входные тексты, которые не соответствуют RFC, десериализатор этого модуля технически соответствует RFC при настройках по умолчанию.
18.2.3.1. Кодировки символов¶Character Encodings
RFC требует, чтобы JSON представлялся с использованием UTF-8, UTF-16 или UTF-32, причём UTF-8 рекомендуется по умолчанию для максимальной совместимости. Соответственно, этот модуль использует UTF-8 в качестве значения по умолчанию для параметра encoding.
Десериализатор этого модуля напрямую работает только с кодировками, совместимыми с ASCII; UTF-16, UTF-32 и другие несовместимые с ASCII кодировки требуют применения обходных путей, описанных в документации к параметру encoding десериализатора.
Согласно RFC это допускается, но не требуется; сериализатор данного модуля по умолчанию использует ensure_ascii=True, экранируя вывод так, чтобы результирующие строки содержали только ASCII-символы.
RFC запрещает добавление метки порядка байтов (BOM) в начало JSON-текста, и сериализатор этого модуля не добавляет BOM в свой вывод.
RFC разрешает, но не требует, чтобы десериализаторы JSON игнорировали начальный BOM во входных данных. Десериализатор этого модуля возбуждает ValueError, когда присутствует начальный BOM.
RFC явно не запрещает строки JSON, содержащие последовательности байтов, которые не соответствуют допустимым символам Unicode (например, непарные суррогаты UTF-16), но отмечает, что они могут вызывать проблемы совместимости.
По умолчанию этот модуль принимает и выводит (когда они присутствуют в исходном str) кодовые точки таких последовательностей.
18.2.3.2. Бесконечные и NaN значения чисел¶Infinite and NaN Number Values
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 можно использовать для изменения этого поведения.
18.2.3.3. Повторяющиеся имена внутри объекта¶Repeated Names Within an Object
RFC указывает, что имена внутри JSON-объекта должны быть уникальными, но не предписывает, как обрабатывать повторяющиеся имена в JSON-объектах. По умолчанию этот модуль не вызывает исключение; вместо этого он игнорирует все, кроме последней пары имя-значение для данного имени:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{u'x': 3}
Параметр object_pairs_hook можно использовать для изменения этого поведения.
18.2.3.4. Значения верхнего уровня, не являющиеся объектом или массивом¶Top-level Non-Object, Non-Array Values
Старая версия JSON, определённая устаревшим RFC 4627, требовала, чтобы
значение верхнего уровня JSON-текста было либо JSON-объектом, либо массивом
(Python dict или list), и не могло быть null, boolean,
числом или строкой. RFC 7159 снял это ограничение, и
этот модуль не реализует и никогда не реализовывал это ограничение ни в своём
сериализаторе, ни в десериализаторе.
Тем не менее, для максимальной совместимости можно добровольно придерживаться этого ограничения.
18.2.3.5. Ограничения реализации¶Implementation Limitations
Некоторые реализации JSON-десериализаторов могут устанавливать ограничения на:
размер принимаемых JSON-текстов
максимальный уровень вложенности JSON-объектов и массивов
диапазон и точность JSON-чисел
содержимое и максимальную длину JSON-строк
Этот модуль не накладывает никаких подобных ограничений, кроме тех, что присущи соответствующим типам данных Python или самому интерпретатору Python.
При сериализации в JSON учитывайте подобные ограничения в приложениях, которые могут потреблять ваш JSON. В частности, JSON-числа часто десериализуются в числа двойной точности IEEE 754 и, следовательно, подчиняются ограничениям диапазона и точности этого представления. Это особенно актуально при сериализации значений Python int чрезвычайно большой величины или при сериализации экземпляров «экзотических» числовых типов, таких как decimal.Decimal.
Сноски
- 1
Как отмечено в списке ошибок RFC 7159, JSON допускает символы U+2028 (LINE SEPARATOR) и U+2029 (PARAGRAPH SEPARATOR) в строках, тогда как JavaScript (начиная с ECMAScript Edition 5.1) – нет.