18.2. jsonJSON 格式的编码器和解码器

2.6 版本中的更新。

JSON (JavaScript 对象符号),由指定 RFC 4627,是基于JavaScript语法的一个子集的轻量级数据交换格式 (ECMA 262 第 3 版)。

json公开了用户所熟悉的标准库marshalpickle模块的API。

对基本的 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]
...         # Let the base class default method raise the 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', ']']

通过Shell使用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)

JSON 是YAML 1.2 的一个子集。通过此模块的默认设置 (尤其是,默认分隔符值) 生成的 JSON 也是一个子集的 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()-支持类文件对象) 使用此转换表

如果skipkeysTrue (默认:False),然后并不是一种基本的类型 (str, unicode, int, long, float, bool, None) 的字典键将被跳过而不是抛出TypeError异常。

If ensure_ascii is True (the default), all non-ASCII characters in the output are escaped with uXXXX sequences, and the result is a str instance consisting of ASCII characters only. If ensure_ascii is False, some chunks written to fp may be unicode instances. This usually happens because the input contains unicode strings or the encoding parameter is used. Unless fp.write() explicitly understands unicode (as in codecs.getwriter()) this is likely to cause an error.

如果是check_circular (默认:True),对容器类型的循环引用检查将被跳过,然后循环的引用将导致OverflowError (或更糟)。

如果allow_nanFalse(默认:True),那么它将是ValueError范围的浮点型-inf inf nan) 从序列化 JSON 的规范,而不是使用 JavaScript 等价物严格按照 (NaN无穷大 -无限)。

如果缩进是一个非负整数,那么 JSON 数组元素和对象成员将漂亮印有该缩进级别。缩进级别为 0,或负面的只能将插入换行符。没有一个(默认值) 选择的最紧凑的表示形式。

因为默认项分隔符是', ',输出可能包含尾随空格缩进指定时。您可以使用separators = (',', ': ')来避免这种情况。

如果分隔符(item_separator, dict_separator)元组),那么它将代替默认的(', ', ': ')分隔符。 (',', ': ')是最紧凑的 JSON 表示。

编码的字符编码为 str 实例,默认为 utf-8。

default(obj)是 obj 的一个函数,它应该返回一个可序列化的版本或抛出TypeError异常。默认值只是引发TypeError

如果sort_keysTrue (默认:False),然后将按关键字排序字典的输出。

若要使用自定义的JSONEncoder子类 (例如一种重写要序列化的其他类型的default ()方法),指定与cls kwarg ;否则将使用JSONEncoder

不同于picklemarshal,JSON 并不是一个框架的协议,所以尝试序列化多个对象与dump()和同一fp的一再呼吁将导致无效的 JSON 文件中了。

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)

序列化对象到 JSON 格式str使用此转换表如果ensure_ascii的结果可能包含非 ASCII 字符,返回的值可能为unicode实例。

参数具有相同的含义,如dump()所示。

JSON 的键/值对中的键都是str类型的。当一个字典转换为 JSON格式 时,字典所有的键都会强制转换成字符串。正因如此,如果一个字典转换为 JSON,然后再转换回一个字典,字典可能将不会等同于原来的那个字典。那就意味着,如果一个字典的键有非字符串形式的,字典将会不同。 loads(dumps(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 以外 (例如拉丁语-1),然后适当的编码必须指定名称。不是 ASCII 基础 (如 UCS-2) 的编码不允许,应包裹着codecs.getreader(encoding)(fp),或只是解码到unicode对象和传递给loads()

object_hook是一个可选的功能,将调用任何对象文本解码 (词典) 的结果。而不是字典,将使用object_hook的返回值。此功能可用于实现自定义的解码器 (例如JSON RPC类暗示)。

object_pairs_hook是一个可选的函数,将调用任何的结果对象文本解码成对有序列表。而不是字典,将使用object_pairs_hook的返回值。此功能可用于实现自定义的解码器,依赖于顺序的键和值对进行解码 (例如,收藏。OrderedDict()会记得的插入顺序)。如果还定义了object_hookobject_pairs_hook具有更高的优先。

2.7 版本中的更改:添加了对object_pairs_hook的支持。

parse_float,如果指定,将使用每个 JSON 浮法要解码的字符串调用。默认情况下,这是相当于float(num_str)这可以用来使用另一种数据类型或解析 JSON 浮桶式 (例如十进制。十进制)。

parse_int,如果指定,将使用每个 JSON int 要解码的字符串调用。默认情况下,这是相当于int(num_str)这可以用来使用另一种数据类型或解析 JSON 整数 (例如浮点数)。

parse_constant,如果指定,将调用以下字符串之一: '-无穷大 ' '无限' '南'这可以用来如果遇到无效的 JSON 号码时引发异常。

2.7 版本中的更改:parse_constant不会被叫到 null,真正的'、 '假' 了。

若要使用自定义的JSONDecoder子类,指定与cls kwarg ;否则将使用JSONDecoder 附加的关键字参数将传递给类的构造函数。

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

使用此转换表将包含JSON文档的s(一个 strunicode实例)

如果sstr实例,并且使用除UTF-8之外的基于ASCII的编码(例如latin-1)编码,则必须指定合适的encoding名称。不允许使用不是基于ASCII (如 UCS-2) 的encoding,应首先向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
object dict
array list
string unicode
number (int) int, long
number (real) float
true True
false False
null None

它还了解NaN无穷大,和-无穷大作为其相应的浮点型值,这是外面的 JSON 规范。

编码决定了用于将解释此实例 (UTF-8,默认情况下) 由解码任何str对象的编码方式。解码unicode对象时,它没有任何影响。

请注意目前只是 ASCII 工作的一个超集的编码,使用其他编码字符串应将作为传入unicode

object_hook,如果指定,将被称为解码的每个 JSON 对象的结果和它的返回值用于替换给定的字典这可以用于提供自定义 deserializations (例如到支持 JSON RPC 类暗示)。

object_pairs_hook,如果指定将调用解码与对排序列表每个 JSON 对象的结果。而不是字典,将使用object_pairs_hook的返回值。此功能可用于实现自定义的解码器,依赖于顺序的键和值对进行解码 (例如,收藏。OrderedDict()会记得的插入顺序)。如果还定义了object_hookobject_pairs_hook具有更高的优先。

2.7 版本中的更改:添加了对object_pairs_hook的支持。

parse_float,如果指定,将使用每个 JSON 浮法要解码的字符串调用。默认情况下,这是相当于float(num_str)这可以用来使用另一种数据类型或解析 JSON 浮桶式 (例如十进制。十进制)。

parse_int,如果指定,将使用每个 JSON int 要解码的字符串调用。默认情况下,这是相当于int(num_str)这可以用来使用另一种数据类型或解析 JSON 整数 (例如浮点数)。

parse_constant,如果指定,将调用以下字符串之一: '-无穷大 ' '无限' '南' '空' '真实' '假'这可以用来如果遇到无效的 JSON 号码时引发异常。

If strict is False (True is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0-31 range, including ' ' (tab), ' ', ' ' and ''.

如果正在反序列化的数据不是一个有效的 JSON 文档,则会引发ValueError

decode(s)

返回s (包含一个 JSON 文档的strunicode实例) 的 Python 表示形式

raw_decode(s)

解码从s strunicode开头的一个 JSON 文档) 的 JSON 文档,并返回 Python 代表性和索引 2 元组在s文档结束的地方。

这可以用来解码从字符串末尾可能包含外部数据的 JSON 文档。

class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])

可扩展的 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)。

如果skipkeysFalse (默认值),然后是TypeError ,尝试不是 str,int,长的钥匙、 浮点数或没有编码。如果skipkeysTrue,只是跳过这些项目。

If ensure_ascii is True (the default), all non-ASCII characters in the output are escaped with uXXXX sequences, and the results are str instances consisting of ASCII characters only. If ensure_ascii is False, a result may be a unicode instance. This usually happens if the input contains unicode strings or the encoding parameter is used.

如果check_circularTrue (默认值),然后列出,字典和自定义编码的对象将编码以防止无限递归 (这会导致OverflowError) 过程中检查循环引用。否则,这种检查发生。

如果allow_nanTrue (默认值),然后无穷大,和-无穷远将作为这种编码。这种行为不是 JSON 规格符合标准,但与大多数基于 JavaScript 编码器和解码器是一致的。否则,它将ValueError编码这种浮游物。

如果sort_keysTrue(默认False),那么字典的输出将按键排序;这是有用的回归测试,以确保在日常的基础上就好比 JSON 序列化。

如果缩进(它是没有在默认情况下) 为非负整数,然后 JSON 数组元素和对象成员将漂亮-打印用的缩进级别。缩进级别是 0 只将插入换行符。都不是最紧凑的表示形式。

因为默认项分隔符是', ',输出可能包含尾随空格缩进指定时。您可以使用分隔符 = (',' ': ')来避免这种情况。

如果指定,分隔符应该是(item_separator, key_separator)元。默认值是(', ', ': ')若要获取最紧凑的 JSON 表示,应指定(',' ': ')消除空白。

如果指定,则默认值为一个函数,否则不能序列化的对象获取调用。它应该返回该对象的 JSON 编码版本或提高TypeError

如果编码不是None,则所有输入的字符串都将改制为 unicode 使用该编码在 JSON 编码之前。默认为 utf-8。

default(o)

在子类中实现此方法,这样,它返回一个可序列化的对象,用于o,或者调用基实现 (以提高TypeError)。

例如,若要支持任意迭代器,可以实现像这样的默认:

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 JSONEncoder.default(self, o)
encode(o)

返回一个 Python 数据结构, o的 JSON 字符串表示形式。举个例子:

>>> 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

JSON 格式由指定 RFC 4627.本节详细描述了本模块级别的法规遵从性与 RFC。为简单起见, JSONEncoderJSONDecoder子类,并且未明确提及,参数不被考虑。

本模块不符合 RFC 以严格的方式,实施一些有效的 JavaScript 但无效 JSON 的扩展。特别是:

  • Top-level non-object, non-array values are accepted and output;
  • Infinite and NaN number values are accepted and output;
  • Repeated names within an object are accepted, and only the value of the last name-value pair is used.

因为 RFC 允许符合 RFC 解析器接受那些不符合 RFC 规范的输入的文本,此模块的串并转换电路是在默认设置下技术上符合 RFC。

18.2.3.1. Character Encodings

RFC 建议能表示 JSON 使用 UTF-8、 UTF-16 或 UTF-32,使用 utf-8 作为默认值。因此,本模块使用 utf-8 作为默认为其编码的参数。

本模块的串并转换电路不仅直接工作与 ASCII 兼容编码 ;Utf-16,UTF-32,以及其他不兼容的 ASCII 编码所需的变通方法反序列化程序的编码参数文档中所述。

RFC 也非规范描述了有限的编码检测技术为 JSON 文本 ;本模块反序列化程序不实现这个或任何其他类型的编码检测。

作为允许,但是不是必需的 RFC,此模块的序列化程序设置ensure_ascii = True默认情况下,从而摆脱输出以便结果字符串仅包含 ASCII 字符。

18.2.3.2. Top-level Non-Object, Non-Array Values

RFC 指定顶级 JSON 文本的值必须是一个 JSON 对象或阵列 (Python字典列表)。本模块的串并转换电路也接受输入的文本组成单独的 JSON null、 布尔值、 数字或字符串值:

>>> 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没有布尔值、 数字和str值作为输入,并将生成输出文本组成单独的顶级 JSON null、 布尔值、 数字或字符串值而不会引发异常:

>>> 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"'

本模块的序列化程序本身并不能包括的方式来执行上述约束。

18.2.3.3. Infinite and NaN Number Values

RFC 不允许无限或 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参数,来改变此行为。

18.2.3.4. 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参数可以用来改变此行为。