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 None
null Для того, чтобы можно было распознавать и другие объекты подкласс должен реализвать метод
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.