首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

json

2.6版本中的新功能。

JSON(JavaScript对象表示法)RFC 7159(废弃RFC 4627)和ECMA-404指定,是一种轻量级的数据交换格式,受JavaScript对象字面值语法的启发(尽管它不是JavaScript的严格子集)[1]。

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

编码基本的Python对象层次结构:

代码语言:javascript
复制
>>> 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"]'

紧凑编码:

代码语言:javascript
复制
>>> import json
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
'[1,2,3,{"4":5,"6":7}]'

漂亮的印刷:

代码语言:javascript
复制
>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True,
...                  indent=4, separators=(',', ': '))
{
    "4": 5,
    "6": 7
}

解码JSON:

代码语言:javascript
复制
>>> 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对象解码:

代码语言:javascript
复制
>>> 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

代码语言:javascript
复制
>>> 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', ']']

json.tool在shell中使用来验证和漂亮打印:

代码语言:javascript
复制
$ 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 也是YAML 1.0和1.1的子集。因此该模块也可以用作YAML串行器。

1.基本用法

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为真(默认:False),那么字典键是一个基本类型(不strunicodeintlongfloatboolNone)将被跳过,而不是养TypeError

如果ensure_ascii为true(缺省值),则输出中的所有非ASCII字符都会使用\uXXXX序列进行转义,结果是str仅包含ASCII字符的实例。如果ensure_ascii为false,则写入fp的某些块可能是unicode实例。这通常发生是因为输入包含unicode字符串或使用编码参数。除非fp.write()明确理解unicode(如在codecs.getwriter())这可能会导致错误。

如果check_circular为false(默认值:)True,那么容器类型的循环引用检查将被跳过,并且循环引用将导致OverflowError(或更糟糕)。

如果allow_nan是假的(默认:True),那么这将是一个ValueError序列化超出范围的float值(naninf-inf在JSON规范的严格遵守)。如果allow_nan是真实的,其JavaScript当量(NaNInfinity-Infinity)将被使用。

如果indent是一个非负整数,那么JSON数组元素和对象成员将与该缩进级别相匹配。缩进级别0或负数只会插入换行符。None(默认)选择最紧凑的表示形式。

注意

由于缺省项目分隔符是', ',输出可能包括指定缩进时的尾部空白。你可以separators=(',', ': ')用来避免这种情况。

如果指定,分隔符应该是一个(item_separator, key_separator)元组。默认情况下,(', ', ': ')使用。要获得最紧凑的JSON表示,您应该指定(',', ':')消除空白。

encoding是str实例的字符编码,默认为UTF-8。

如果指定,则默认值应为针对不能以其他方式进行序列化的对象调用的函数。它应该返回一个JSON可编码版本的对象或引发一个TypeError。如果未指定,TypeError则引发。

如果sort_keys为true(默认值:)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)

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(包含JSON文档的.read()支持类文件对象)反序列化为 Python对象。

如果fp的内容使用非UTF-8(例如latin-1)的基于ASCII的编码进行编码,则必须指定适当的编码名称。不是基于ASCII的编码(例如UCS-2)是不允许的,应该用包装codecs.getreader(encoding)(fp)或简单解码到一个unicode对象并传递给它loads()

object_hook是一个可选函数,它将被解码的任何对象字面值的结果调用(a 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的字符串进行解码。默认情况下,这相当于int(num_str)。这可以用来为JSON整数使用另一种数据类型或解析器(例如float)。

parse_constant:如果指定,将与下列字符串之一叫'-Infinity''Infinity''NaN'。如果遇到无效的JSON号码,这可以用来引发异常。

在版本2.7中更改:parse_constant不再被'null','true','false'调用。

要使用自定义JSONDecoder子类,请使用clskwarg 指定它; 否则JSONDecoder使用。其他关键字参数将传递给该类的构造函数。

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

反序列化小号(一个strunicode含JSON文档实例)使用该转换表Python对象。

如果s是一个str实例,并且使用UTF-8以外的基于ASCII的编码(例如latin-1)进行编码,则必须指定适当的编码名称。不是基于ASCII的编码(如UCS-2)是不允许的,应该首先解码unicode

其他论点的含义与之相同load()

2.编码器和解码器

class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

简单的JSON解码器。

默认情况下,在解码中执行以下翻译:

JSON

Python

目的

字典

排列

名单

统一

数字(int)

int,long

数量(实际)

浮动

真正

真正

空值

没有

它也理解NaNInfinity并且-Infinity作为它们相应的float值,它超出了JSON规范。

编码决定用于解释str由此实例解码的任何对象的编码(默认为UTF-8)。解码unicode对象时不起作用。

请注意,目前只有编码是ASCII工作的超集,其他编码的字符串应该以as的形式传入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的字符串进行解码。默认情况下,这相当于int(num_str)。这可以用来为JSON整数使用另一种数据类型或解析器(例如float)。

parse_constant:如果指定,将与下列字符串之一叫'-Infinity''Infinity''NaN'。如果遇到无效的JSON号码,这可以用来引发异常。

如果strict为假(True是默认值),那么控制字符将被允许在字符串内。此上下文中的控制字符是字符代码在0-31范围内的字符,包括'\t'(制表符)'\n''\r''\0'

如果被反序列化的数据不是有效的JSON文档,ValueError则会引发。

decode(s)

返回s(包含JSON文档的实例str或Python unicode实例)的Python表示形式。

raw_decode(s)

sstrunicode从JSON文档开始)解码JSON文档,并在文档结束的s中返回Python表示形式的2元组和索引。

这可以用来从一个字符串解码JSON文档,该字符串可能在最后有多余的数据。

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

用于Python数据结构的可扩展JSON编码器。

默认支持以下对象和类型:

Python

JSON

字典

目的

列表,元组

排列

str,unicode

int,long,float

真正

真正

没有

空值

为了扩展这个以识别其他对象,子类并default()使用另一个方法实现一个方法,o如果可能的话,该方法返回一个可序列化对象,否则它应该调用超类实现(提升TypeError)。

如果skipkeys为false(缺省值),那么它将TypeError尝试编码不是str,int,long,float或None。如果skipkeys为true,则简单地跳过这些项目。

如果ensure_ascii为true(缺省值),则输出中的所有非ASCII字符都会被\uXXXX序列转义,并且结果是str仅由ASCII字符组成的实例。如果ensure_ascii为false,则结果可能是一个unicode实例。如果输入包含unicode字符串或使用编码参数,通常会发生这种情况。

如果check_circular为true(默认值),那么在编码期间将检查列表,字典和自定义编码对象的循环引用,以防止无限递归(这会导致OverflowError)。否则,不会进行这种检查。

如果allow_nan为真(默认值),然后NaNInfinity-Infinity将被编码为这样。这种行为不符合JSON规范,但与大多数基于JavaScript的编码器和解码器一致。否则,这将是一个ValueError编码这样的浮游物。

如果sort_keys为true(默认值:)False,则字典的输出将按键排序; 这对于回归测试非常有用,可以确保JSON序列化可以在日常的基础上进行比较。

如果indent是一个非负整数(None默认情况下),那么JSON数组元素和对象成员将会与该缩进级别相匹配。缩进级别0只会插入换行符。None是最紧凑的代表。

注意

由于缺省项目分隔符是', ',输出可能包括指定缩进时的尾部空白。你可以separators=(',', ': ')用来避免这种情况。

如果指定,分隔符应该是一个(item_separator, key_separator)元组。默认情况下,(', ', ': ')使用。要获得最紧凑的JSON表示,您应该指定(',', ':')消除空白。

如果指定,则默认值应为针对不能以其他方式进行序列化的对象调用的函数。它应该返回一个JSON可编码版本的对象或引发一个TypeError。如果未指定,TypeError则引发。

如果编码不是None,那么所有输入字符串将在JSON编码之前使用该编码转换为unicode。默认值是UTF-8。

default(o)

在子类中实现此方法,以便返回o的可序列化对象,或调用基本实现(以提高a TypeError)。

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

代码语言:javascript
复制
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数据结构的JSON字符串表示形式o。例如:

代码语言:javascript
复制
>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'

iterencode(o)

对给定对象o进行编码,并将每个字符串表示视为可用。例如:

代码语言:javascript
复制
for chunk in JSONEncoder().iterencode(bigobject):
    mysocket.write(chunk)

3.标准兼容性和互操作性

JSON格式由RFC 7159ECMA-404指定。本节详细介绍了该模块对RFC的遵从级别。为了简单起见,JSONEncoderJSONDecoder亚类和除了明确提及的那些其它参数,都没有考虑。

该模块不严格遵守RFC,实现了一些有效的JavaScript但不是有效的JSON的扩展。尤其是:

  • 无限和NaN数值被接受和输出;
  • 对象中的重复名称将被接受,并且只使用最后一个名称 - 值对的值。

由于RFC允许RFC兼容的解析器接受不符合RFC的输入文本,因此该模块的解串器在技术上符合RFC默认设置。

3.1。字符编码

RFC要求使用UTF-8,UTF-16或UTF-32来表示JSON,UTF-8是最大互操作性的推荐默认值。因此,该模块使用UTF-8作为其编码参数的默认值。

该模块的解串器仅直接与ASCII兼容的编码一起工作; UTF-16,UTF-32和其他ASCII不兼容的编码需要使用文档中描述的解串器编码参数的解决方法。

根据RFC的规定,尽管不是必需的,但该模块的序列化程序默认情况下会设置ensure_ascii = True,从而转义输出,以便生成的字符串仅包含ASCII字符。

RFC禁止将字节顺序标记(BOM)添加到JSON文本的开头,并且此模块的串行器不会将BOM添加到其输出中。RFC允许但不要求JSON解串器忽略其输入中的初始BOM。ValueError当存在初始BOM时,该模块的解串器会产生一个。

RFC没有明确禁止包含与有效的Unicode字符不对应的字节序列的JSON字符串(例如不成对的UTF-16替代品),但是它确实注意到它们可能导致互操作性问题。默认情况下,该模块接受并输出(当存在于原始中str)用于这种序列的代码点。

3.2。无限和NaN数值

RFC不允许表示无限或NaN号码值。尽管如此,在默认情况下,该模块能够接受和输出Infinity-Infinity以及NaN就好像它们是有效的JSON数字面值:

代码语言:javascript
复制
>>> # 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参数来改变这种行为。

3.3。对象中的重复名称

RFC指定JSON对象中的名称应该是唯一的,但不要求JSON对象中的重复名称应该如何处理。默认情况下,该模块不会引发异常; 相反,它忽略了给定名称以外的所有名称 - 值对:

代码语言:javascript
复制
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{u'x': 3}

object_pairs_hook参数可以用来改变这种行为。

3.4。顶级非对象,非数组值

由过时的RFC 4627指定的JSON的旧版本要求JSON文本的顶级值必须是JSON对象或数组(Python dictlist),并且不能是JSON null,布尔值,数字或字符串值。RFC 7159删除了这个限制,而且这个模块没有,也没有在其串行器或解串器中实现这个限制。

无论如何,为了获得最大的互操作性,您可能希望自己自愿遵守限制。

3.5。实施限制

一些JSON解串器实现可能会对以下内容设置限制:

  • 接受的JSON文本的大小
  • JSON对象和数组的最大嵌套级别
  • JSON数字的范围和精度
  • JSON字符串的内容和最大长度

除了相关的Python数据类型本身或Python解释器本身以外,本模块不会强加任何限制。

序列化为JSON时,请注意可能会使用JSON的应用程序中的任何此类限制。特别是,JSON数字被反序列化为IEEE 754双精度数字并且因此受制于该表示的范围和精度限制是很常见的。当序列化int极大数量的Python 值时,或者在序列化“奇异”数字类型的实例时,这尤其重要decimal.Decimal

1

正如RFC 7159勘误中所述,JSON允许在字符串中使用文字U + 2028(LINE分隔符)和U + 2029(PARAGRAPH SEPARATOR)字符,而JavaScript(从ECMAScript版本5.1开始)则不允许。

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com