json
json — JSON encoder and decoder
2.6版本中的新功能。
JSON(JavaScript对象表示法)由RFC 7159
(废弃RFC 4627
)和ECMA-404指定,是一种轻量级的数据交换格式,受JavaScript对象字面值语法的启发(尽管它不是JavaScript的严格子集)[1]。
json
公开了标准库marshal
和pickle
模块用户熟悉的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', ']']
json.tool
在shell中使用来验证和漂亮打印:
$ 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
),那么字典键是一个基本类型(不str
,unicode
,int
,long
,float
,bool
,None
)将被跳过,而不是养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
值(nan
,inf
,-inf
在JSON规范的严格遵守)。如果allow_nan
是真实的,其JavaScript当量(NaN
,Infinity
,-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
使用。
注意
不像pickle
和marshal
,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
子类,请使用cls
kwarg 指定它; 否则JSONDecoder
使用。其他关键字参数将传递给该类的构造函数。
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
反序列化小号
(一个str
或unicode
含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 |
数量(实际) | 浮动 |
真正 | 真正 |
假 | 假 |
空值 | 没有 |
它也理解NaN
,Infinity
并且-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)
从s
(str
或unicode
从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
为真(默认值),然后NaN
,Infinity
和-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
)。
例如,要支持任意迭代器,可以像这样实现默认值:
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)
返回Pytho
n数据结构的JSON字符串表示形式o
。例如:
>>> JSONEncoder().encode{"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
iterencode(o)
对给定对象o进行
编码,并将每个字符串表示视为可用。例如:
for chunk in JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
3.标准兼容性和互操作性
JSON格式由RFC 7159
和ECMA-404指定。本节详细介绍了该模块对RFC的遵从级别。为了简单起见,JSONEncoder
和JSONDecoder
亚类和除了明确提及的那些其它参数,都没有考虑。
该模块不严格遵守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数字面值:
>>> # 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对象中的重复名称应该如何处理。默认情况下,该模块不会引发异常; 相反,它忽略了给定名称以外的所有名称 - 值对:
>>> 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 dict
或list
),并且不能是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开始)则不允许。 |
---|