json — преобразователь для JSON¶
New in version 2.6.
JSON (JavaScript Object Notation), определённый в RFC 4627, является простым форматом обмена данными, основанным на подмножестве синтаксиса JavaScript syntax (ECMA-262 3rd edition).
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)
...
>>> 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 -mjson.tool
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -mjson.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Note
JSON является подмножеством YAML 1.2. JSON, создаваемый этим модулем при настройках по умолчанию (в частности, при значениях по умолчанию для разделителей) также является подмножеством 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, encoding="utf-8", default=None, sort_keys=False, **kw)[source]¶ Сериализует obj как форматированный JSON поток в fp (файло-подобный объект, поддерживающий метод
.write()) используя эту таблицу преобразования.Если skipkeys =
True(по умолчанию:False), тогда ключи словаря не базового типа (str,unicode,int,long,float,bool,None) будут проигнорированны, вместо того, чтобы вызывать исключениеTypeError.Если ensure_ascii =
True(по умолчанию), все не-ASCII символы в выводе будут экранированы последовательностями\uXXXX, и результатом будет строка, содержащая только ASCII символы. Если ensure_ascii =False, то некоторые части, записываемые в fp могут быть экземлярамиunicode. Обычно это происходит из-за того, что исходный поток содержит юникод или используется параметр encoding. Если Вы не уверены, чтоfp.write()понимает юникод (как вcodecs.getwriter()), то это практически наверняка приведёт к ошибке.Если check_circular =
False(по умолчанию:True), тогда проверка циклических ссылок для типов контейнера будет пропущена, а такие ссылки будут вызывать OverflowError (или ещё хуже).Если allow_nan =
False(по умолчанию:True), при попытке сериализовать значение с запятой, выходящее за допустимые пределы, будте вызыватьValueError(nan,inf,-inf) в строгом соответствии со спецификацией JSON, вместо того, чтобы использовать эквиваленты из JavaScript (NaN,Infinity,-Infinity).Если indent является неотрицательным числом, тогда массивы и объекты в JSON будут выводиться с этим уровнем отступа. Если уровень отступа 0 или отрицательный, то вместо этого будут просто использоваться новые строки. Значение по умолчанию
Noneотражает наиболее компактное представление.Note
Так как разделителем элементов по умолчанию является
', ', то вывод может включать “волочащиеся” пробелы, если задан уровень отступа. Для того, чтобы этого избежать Вы можете использоватьseparators=(',', ': ').Если separators является кортежем
(разделитель_элементов, разделитель_словаря), тогда он будет использоваться вместо значения по умолчанию(', ', ': ').(',', ':')даёт наиболее компактное представление JSON.encoding - кодировка для экземпляров str, по умолчанию - UTF-8.
default(obj) - функция, которая должна вернуть сериализованную версию obj или вызвать :exc:
TypeError. Значение по умолчанию просто возбуждает :exc:TypeError.Если sort_keys =
True(по умолчанию:False), тогда ключи выводимого словаря будут отсортированы.Для того, чтобы использовать собственный подкласс :class:
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)[source]¶ Сериализует obj в строку JSON-формата при помощи таблицы преобразования. Если ensure_ascii =
False, то результат может содержать не-ASCII символы и возвращаемое значение может быть экзмепляромunicode.Аргументы имеют то же значение, что и для
dump().Note
Ключи в парах ключ/значение в JSON всегда являются строками. Когда словарь конвертируется в JSON, все ключи словаря преобразовываются в строки. В результате этого, если словарь сперва преобразовать в JSON, а затем обратно словарь, то можно не получить словарь, идентичный исходному. Другими словами,
loads(dumps(x)) != xесли x имеет нестроковые ключи.
-
json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])[source]¶ Десериализует fp (файло-подобный объект, содеращий JSON документ, поддерживающий
.read()) в объект Python, используя таблицу преобразования).Если содержимое fp закодировано кодировкой на основе ASCII, а не UTF-8 (например, latin-1), тогда должно быть указана соответствующая кодировка. Кодировки, не основанные на ASCII (такие как UCS-2) использовать нельзя и в таком случае нужно использовать обёртку ||codecs.getreader(encoding)(fp)||, или просто декодировать в объект
unicodeи передать вloads().object_hook - опциональная функция, которая применяется к резальтату декодирования объекта (
dict). Использоваться будет значение, возвращаемое этой функцией, а не полученный словарь. Эта возможность полезна для реализации собственных декодировщиков (например, JSON-RPC class hinting).object_pairs_hook - опциональная функция, которая применяется к результату декодирования к результату декодирования объекта с определённой последовательностью пар ключ/значение. Будет использован результат, возвращаемый функцией, вместо исходного словаря. Эта возможность полезна для реализации пользовательских декодировщиков, которые опирваются на порядок пар ключ/значение (например,
collections.OrderedDict()будет помнить порядок добавления). Если задан так же object_hook, то приоритет отдаётся object_pairs_hook.Changed in version 2.7: Добавлена поддержка object_pairs_hook.
parse_float, если определён, будет вызван для каждого значения JSON с плавающей точкой для его декодирования. По умолчанию, это эквивалентно
float(num_str). Можно использовать другой тип данных или парсер для этого значения (например,decimal.Decimal).parse_int, если определён, будет вызван для строки с числовым значением JSON, чтобы его декодировать. По умолчанию эквивалентно
int(num_str). Это можно использовать для других типов данных или парсеров для целых чисел JSON (например,float).parse_constant, если определён, будет вызван для следующих строк:
'-Infinity','Infinity','NaN'. Может быть использовано для возбуждения ошибок при обнаружении ошибочных чисел JSON.Changed in version 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]]]]]]]])[source]¶ Десериализует s (экземпляр
strилиunicode, содержащий документ JSON) в объект Python при помощи таблицы преобразования.Если s является экземлпяром
strи закодировано кодировкой на основе ASCII, а не UTF-8 (например, latin-1), тогда должно быть указана эта кодировка. Кодировки, не основанные на ASCII (такие как UCS-2) использовать нельзя и в таком случае нужно его сперва преоразовать вunicode.Остальные аргументы аналогичны аргументам в
load().
Кодировщики и Декодировщики¶
-
class
json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])[source]¶ Простой декодер JSON.
Выполняет следующие преобразования при декодировании:
JSON Python object dict array list string unicode number (int) int, long number (real) float true True false False null NoneОн так же понимает
NaN,Infinity, и-Infinityкак соответствующие значенияfloat, которые находятся за пределами спецификации JSON.encoding определяет кодировку, которая используется для интерпретации объектов
str, закодированных в этом экземпляре (UTF-8 по умолчанию). Ни на что не влияет при декодировании объектовunicode.Обратите внимание, что на данный момент работают только кодировки, которые являются расширением ASCII, строки в други кодировках должны передаваться как
unicode.object_hook, если определён, будет вызван для результата декодирования каждого JSON объекта и возвращаемое им значение и будет использовано вместо декодированного значения. Это может быть использовано для пользовательской десериализации (например, для поддержки JSON-RPC class hinting).
object_pairs_hook, если определён, будет вызван для декодированного объекта JSON с упорядоченным списком пар. Возвращаемое значение object_pairs_hook будет использовано вместо декодированного словаря. Эту возможность можно использовать для реализации пользовательских декодировщиков, которые опираются на порядок пар ключ/значение в декодированном результате (например,
collections.OrderedDict()запоминает порядок добавления элементов). Если object_hook тоже определён, object_pairs_hook имеет приоритет.Changed in version 2.7: Добавлена поддержка object_pairs_hook.
parse_float, если определён, будет вызван для каждого значения JSON с плавающей точкой для его декодирования. По умолчанию, это эквивалентно
float(num_str). Можно использовать другой тип данных или парсер для этого значения (например,decimal.Decimal).parse_int, если определён, будет вызван для строки с числовым значением JSON, чтобы его декодировать. По умолчанию эквивалентно
int(num_str). Это можно использовать для других типов данных или парсеров для целых чисел JSON (например,float).parse_constant, если определён, будет вызван для следующих строк:
'-Infinity','Infinity','NaN''null','true','false'. Может быть использовано для возбуждения ошибок при обнаружении ошибочных чисел JSON.Если strict =
False(по умолчанию -True), тогда внутри строки могут быть использованы управляющие симовлы. В данном контексте управляющие символы - это символы с кодами в интервале 0-31, включая'\t'(tab),'\n','\r'и'\0'.-
decode(s)[source]¶ Возвращает представление Python для s (экзмемпляр
strилиunicode, содержащий документ JSON)
-
raw_decode(s)[source]¶ Декодирует документ JSON из s (экзмемпляр
strилиunicode, содержащий документ JSON) и возвращает кортеж из 2-х элементов: представление Python и индекс строки s, на которой заканчивается документ.Это можно использовать для декодирования JSON документа из строки, который может иметь дополнительные данные в конце.
-
-
class
json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])[source]¶ Расширяемый кодировщик JSON для структур данных Python.
Поддерживает следующие объекты и типы данных по умолчанию:
Python JSON dict object list, tuple array str, unicode string int, long, float number True true False false Nonenull Для того, чтобы можно было распознавать и другие объекты подкласс должен реализвать метод
default(), который должен возвращаеть сериализуемый объект дляo, если это возможно, в противном случае он должен вызвать реализацию родительского класса (для вызоваTypeError).Если skipkeys =
False(по умолчанию), возбуждаетсяTypeErrorпри попытке закодировать ключ, не являющийся str, int, long, float или None. В противном случае эти элементы просто игнорируются.Если ensure_ascii =
True(по умолчанию), все не-ASCII символы в выводе экранируются последовательностями\uXXXX, и результатом является строка, содержащая только ASCII символы. В противном случае результатом может оказаться экземплярunicode. Обычно это происходит в случае, когда ввод содежит строки юникода или используется параметр encoding.Если check_circular =
True(по умолчанию), тогда списки, словари и вручную закодированные объекты проверяются на циклические ссылки при кодировании для предотвращения бесконечной рекурсии (что может привести кOverflowError). В противном случае такая проверка не проводится.Если allow_nan =
True(по умолчанию), тогдаNaN,Infinity, и-Infinityбудут закодированы. Это поведение не соответствует спецификации, но допустимо большинством основных кодировщиков и декодировщиков JavaScript. В противном случае будет вызвано исключениеValueError.Если sort_keys =
True(по умолчаниюFalse), тогда выводимый словарь будет отсортирован по именам ключей; это полезно для регрессивного тестирования чтобы убедиться, что сериализация JSON может быть сравнена по дням (on a day-to-day basis).Если indent не отрицательное число (по умолчанию
None), тогда массивы и объекты JSON будут выведены с этим уровнем отступа. Уровень отсутпа 0 будет лишь добавлять новые строки.Noneдаёт наиболее компактное представление.Note
Так как разделителем элементов по умолчанию является
', ', то вывод может включать “волочащиеся” пробелы, если задан уровень отступа. Для того, чтобы этого избежать Вы можете использоватьseparators=(',', ': ').Если separators является кортеж
(разделитель_элементов, разделитель_словаря), тогда он будет использоваться вместо значения по умолчанию(', ', ': ').(',', ':')даёт наиболее компактное представление JSON.Если задано, то default - это функция, которая вызывается для объектов, которые не могут быть сериализованы. Она должна возвращать JSON кодированную версию для объекта или возбуждать
TypeError.Если encoding не
None, то все вводимые строки будут преобразованы в юникод, используя эту кодировку. По умолчанию это UTF-8.-
default(o)[source]¶ Реализуйте этот метод в подкласе. Он возвращает сериализуемый объект для o, или вызывает базовую реализацию (для вызова
TypeError).Например, чтобы поддерживать произвольные итераторы, Вы можете реализовать его таким образом:
def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Пусть базовый класс вызовет исключение TypeError return JSONEncoder.default(self, o)
-
Стандартные уступки¶
Формат JSON определён в RFC 4627. Этот раздел описывает соответствие уровня модуля этому RFC. Для простоты, подклассы JSONEncoder и JSONDecoder, и параметры, отличные от явноупомянутых, не поддерживаются.
Этот модуль не строго соответствует RFC, реализуя некоторые расширения, которые корректны для JavaScript, но не для JSON. В частности:
- Не-объекты верхнего уровня и не-массивы принимаются и выводятся
- Значения Infinite и NaN принимаются и выводятся
- Повторяющиеся имена в объекте принимаются и выводится только значение последней пары ключ/значение
Так как RFC разрешает RFC-поддерживающим парсерам принимать вводимый текст, который не соответствует RFC, в этом десериализер модуля технически соответствует RFC при настройках по умолчанию.
Кодировки символов¶
RFC рекомендует, чтобы JSON был представлен в UTF-8, UTF-16, или UTF-32, с UTF-8 по умолчанию. Соответственно, этот модуль использует по умолчанию UTF-8.
Десериализатор модуля напрямую работает только с ASCII-совместимой кодировкой; UTF-16, UTF-32, и другие ASCII-несовместимые кодировки требуют предварительной обработки, как это описанов документации, в разделе про параметр encoding десериализации.
RFC также описывает ограниченную технику определения кодировки для JSON текста; десериализатор этого модуля не реализует никакой техники для определения кодировки.
Согласно тому, что разрешено, но не требуется согласно RFC, сериализатор этого модуля по умолчанию устанавливает ensure_ascii=True, таким образом в выводе будут находиться только ASCII символы.
Значения верхнего уровня, не являющиеся объектами или массивами¶
RFC определяет, что значения верхнего уровня в JSON тексте должны быть либо JSON объектами, либо массивами (dict или list Python). Десериализор этого модуля также принимает текст, состоящий исключительно из значений null, boolean, number, или string JSON:
>>> just_a_json_string = '"spam and eggs"' # Not by itself a valid JSON text
>>> json.loads(just_a_json_string)
u'spam and eggs'
Сам по себе этот модуль не вклюает способа, который позволили бы обозначить этот текст как недопустимый. Так же и сериализатор этого модуля принимает значения Python None, bool, numeric, и str на вход и генерирует выходной текст, содержащий исключительно значения JSON верхнего уровня null, boolean, number, или string без возбуждени исключения:
>>> neither_a_list_nor_a_dict = u"spam and eggs"
>>> json.dumps(neither_a_list_nor_a_dict) # The result is not a valid JSON text
'"spam and eggs"'
Сериализатор данного модуля сам по себе не предоставляет способ обеспечить вышеупомянутые ограничения.
Значения Infinite и NaN¶
RFC не допускает представления для занчений infinite или 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 должны быть уникальными, но не определяет, как должны обрабатываться повторяющиеся имена. По умолчанию, этот модуль не вызывает исключения, вместо этого он игнорирует все пары ключ/значение, кроме последней:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{u'x': 3}
Для изменения этого поведения может использоваться параметр object_pairs_hook.