19.2。 json
- JSON编码器和解码器¶
源代码: Lib / json / __ init __。py
JSON (JavaScript Object Notation), specified by RFC 7159 (which obsoletes RFC 4627) and by ECMA-404, is a lightweight data interchange format inspired by JavaScript object literal syntax (although it is not a strict subset of 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('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io 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))
{
"4": 5,
"6": 7
}
解码JSON:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['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)
...
>>> json.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验证和pretty-print:
$ echo '{"json":"obj"}' | python -m json.tool
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
有关详细文档,请参见Command Line Interface。
注意
JSON是YAML 1.2的子集。由此模块的默认设置(特别是默认的分隔符值)生成的JSON也是YAML 1.0和1.1的子集。因此,该模块也可以用作YAML串行器。
19.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, default=None, sort_keys=False, **kw)¶ 将obj序列化为fp(a
.write()
- 支持file-like object使用此conversion table。If skipkeys is true (default:
False
), then dict keys that are not of a basic type (str
,int
,float
,bool
,None
) will be skipped instead of raising aTypeError
.json
模块总是产生str
对象,而不是bytes
对象。因此,fp.write()
必须支持str
输入。如果ensure_ascii为true(默认值),则输出将保证所有传入的非ASCII字符都转义。如果ensure_ascii为false,则这些字符将按原样输出。
如果check_circular为false(默认值:
True
),则将跳过容器类型的循环引用检查,循环引用将导致OverflowError
如果allow_nan为false(默认值:
True
),则将是ValueError
序列化超出范围float
值(nan
,inf
,-inf
),严格遵守JSON规范。如果allow_nan为true,则将使用与其等效的JavaScript代码(NaN
,Infinity
,-Infinity
)。如果缩进是非负整数或字符串,那么JSON数组元素和对象成员将以该缩进级别打印。缩进级别0,负数或
""
将只插入换行符。None
(默认值)选择最紧凑的表示。使用正整数缩进缩进,每个级别有许多空格。如果缩进是字符串(例如"\t"
),则该字符串用于缩进每个级别。在版本3.2中更改:允许缩进的字符串以及整数。
如果指定,分隔符应为
(item_separator, key_separator)
元组。The default is(', ', ': ')
if indent isNone
and(',', ': ')
otherwise. 要获得最紧凑的JSON表示,应指定(',', ':')
在版本3.4中更改:使用
(',', ': ')作为默认值,如果缩进不是
None
。如果指定,默认应该是一个函数,为不能被序列化的对象调用。它应该返回对象的JSON可编码版本或引发
TypeError
。如果未指定,则会引发TypeError
。如果sort_keys为真(默认值:
False
),则字典的输出将按键排序。要使用自定义
JSONEncoder
子类(例如覆盖default()
方法以序列化其他类型),使用cls kwarg指定它;否则使用JSONEncoder
。
-
json.
dumps
(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶ 使用此conversion table将obj序列化为JSON格式的
str
。参数具有与dump()
中相同的含义。注意
Unlike
pickle
andmarshal
, JSON is not a framed protocol, so trying to serialize multiple objects with repeated calls todump()
using the same fp will result in an invalid JSON file.注意
JSON的键/值对中的键始终为
str
类型。当字典转换为JSON时,字典的所有键都会强制转换为字符串。因此,如果字典转换为JSON然后回到字典,字典可能不等于原始字典。也就是说,如果x具有非字符串键,则载入(dumps(x)) != x
-
json.
load
(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶ Deserialize fp (a
.read()
-supporting file-like object containing a JSON document) to a Python object using this conversion table.object_hook是一个可选的函数,它将被任何对象字面值解码(
dict
)的结果调用。将使用object_hook的返回值而不是dict
。该特征可以用于实现定制解码器(例如,JSON-RPC类提示)。object_pairs_hook是一个可选的函数,它将使用任何对象字面值的结果进行调用,并使用对的有序列表进行解码。将使用object_pairs_hook的返回值,而不是
dict
。该特征可以用于实现依赖于键和值对被解码的顺序的自定义解码器(例如,collections.OrderedDict()
将记住插入的顺序)。如果还定义了object_hook,则object_pairs_hook优先。在版本3.1中已更改:添加对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数字。在版本3.1中更改: parse_constant不会在“null”,“true”和“false”上调用。
要使用自定义
JSONDecoder
子类,请使用cls
kwarg;否则使用JSONDecoder
。额外的关键字参数将被传递给类的构造函数。如果反序列化的数据不是有效的JSON文档,则会引发
JSONDecodeError
。
-
json.
loads
(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶ 使用此conversion table将包含JSON文档的s(a
str
实例)解压缩为Python对象。其他参数与
load()
中含义相同,除了编码,它被忽略和弃用。如果反序列化的数据不是有效的JSON文档,则会引发
JSONDecodeError
。
19.2.2. Encoders and Decoders¶
- class
json.
JSONDecoder
(object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)¶ 简单的JSON解码器。
默认情况下,在解码时执行以下翻译:
JSON Python 目的 命令 数组 列表 串 str number(int) int 数字(实数) 浮动 真正 真正 假 假 空值 没有 它还将
NaN
,Infinity
和-Infinity
理解为它们对应的float
值, 。object_hook(如果指定)将使用每个解析的JSON对象的结果进行调用,其返回值将用于替换给定的
dict
。这可以用于提供定制反序列化(例如,以支持JSON-RPC类提示)。object_pairs_hook(如果指定)将使用对的有序列表解码的每个JSON对象的结果进行调用。将使用object_pairs_hook的返回值,而不是
dict
。该特征可以用于实现依赖于键和值对被解码的顺序的自定义解码器(例如,collections.OrderedDict()
将记住插入的顺序)。如果还定义了object_hook,则object_pairs_hook优先。在版本3.1中已更改:添加对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'
,'null'
,'true'
,'false'
。这可以用于引发异常,如果遇到无效的JSON数字。如果strict为false(
True
是默认值),则在字符串中将允许控制字符。在此上下文中的控制字符是具有在0-31范围内的字符代码的字符,包括'\t'
(tab),'\n'
,'\r'
和'\0'
。如果反序列化的数据不是有效的JSON文档,则会引发
JSONDecodeError
。-
decode
(s)¶ 返回s(包含JSON文档的
str
实例)的Python表示形式。如果给定的JSON文档无效,则会引发
JSONDecodeError
。
-
- class
json.
JSONEncoder
(skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)¶ 用于Python数据结构的可扩展JSON编码器。
默认情况下支持以下对象和类型:
Python JSON 命令 目的 列表,元组 数组 str 串 int,float,int-&float-derived枚举 数 真正 真正 假 假 没有 空值 在版本3.4中更改:添加了对int和float派生的Enum类的支持。
要扩展它以识别其他对象,使用另一个返回
o
可序列化对象的方法,子类化并实现default()
方法,否则应调用超类实现(to引发TypeError
)。如果skipkeys为false(默认值),则会尝试对非str,int,float或None的键进行编码的
TypeError
。如果skipkeys为true,则此类项目将被直接跳过。如果ensure_ascii为true(默认值),则输出将保证所有传入的非ASCII字符都转义。如果ensure_ascii为false,则这些字符将按原样输出。
如果check_circular为true(默认值),则在编码期间将检查列表,diction和自定义编码对象的循环引用,以防止无限递归(这将导致
OverflowError
否则,不进行这样的检查。If allow_nan is true (the default), then
NaN
,Infinity
, and-Infinity
will be encoded as such. 此行为不符合JSON规范,但与大多数基于JavaScript的编码器和解码器一致。否则,将对此类浮点进行编码为ValueError
。如果sort_keys为真(默认值:
False
),那么字典的输出将按键排序;这对于回归测试非常有用,以确保JSON序列化可以在每天的基础上进行比较。如果缩进是非负整数或字符串,那么JSON数组元素和对象成员将以该缩进级别打印。缩进级别为0,负数或
""
将只插入换行符。None
(默认值)选择最紧凑的表示。使用正整数缩进缩进,每个级别有许多空格。如果缩进是字符串(例如"\t"
),则该字符串用于缩进每个级别。在版本3.2中更改:允许缩进的字符串以及整数。
如果指定,分隔符应为
(item_separator, key_separator)
元组。The default is(', ', ': ')
if indent isNone
and(',', ': ')
otherwise. 要获得最紧凑的JSON表示,应指定(',', ':')
在版本3.4中更改:使用
(',', ': ')作为默认值,如果缩进不是
None
。如果指定,默认应该是一个函数,为不能被序列化的对象调用。它应该返回对象的JSON可编码版本或引发
TypeError
。如果未指定,则会引发TypeError
。-
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 json.JSONEncoder.default(self, o)
-
encode
(o)¶ 返回Python数据结构(o)的JSON字符串表示形式。例如:
>>> json.JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
-
iterencode
(o)¶ 编码给定对象o,并将每个字符串表示形式设置为可用。例如:
for chunk in json.JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
-
19.2.4. Standard Compliance and Interoperability¶
JSON格式由 RFC 7159和ECMA-404指定。本节详细说明此模块符合RFC的级别。为了简单起见,不考虑JSONEncoder
和JSONDecoder
子类以及除明确提及的参数之外的参数。
此模块以严格的方式不符合RFC,实现一些有效的JavaScript但不是有效的JSON的扩展。尤其是:
- 接受和输出无限和NaN数值;
- 接受对象内的重复名称,并且仅使用最后名称/值对的值。
由于RFC允许RFC兼容的解析器接受不符合RFC的输入文本,所以该模块的解串器在默认设置下技术上符合RFC。
19.2.4.1. Character Encodings¶
RFC要求使用UTF-8,UTF-16或UTF-32来表示JSON,为了实现最大的互操作性,推荐使用UTF-8。
RFC允许(尽管不是必需的),此模块的序列化器默认设置为ensure_ascii = True,从而转义输出,以使结果字符串只包含ASCII字符。
除了ensure_ascii参数之外,此模块严格按照Python对象和Unicode strings
并且因此不另外直接解决字符编码的问题。
RFC禁止在JSON文本的开头添加字节顺序标记(BOM),并且此模块的序列化程序不会向其输出添加BOM。RFC允许(但不要求)JSON解串器在其输入中忽略初始BOM。当存在初始BOM时,此模块的解串器引发ValueError
。
RFC没有明确禁止包含不对应于有效Unicode字符的字节序列的JSON字符串。不成对的UTF-16代理),但它确实注意到,它们可能导致互操作性问题。默认情况下,此模块接受和输出(当存在于原始str
)这样的序列的代码点。
19.2.4.2. Infinite and NaN Number Values¶
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参数可用于更改此行为。
19.2.4.3. Repeated Names Within an Object¶
RFC指定JSON对象中的名称应该是唯一的,但不要求如何处理JSON对象中的重复名称。默认情况下,此模块不引发异常;相反,它忽略除了给定名称的最后一个名称/值对之外的所有值:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
可以使用object_pairs_hook参数更改此行为。
19.2.4.4. Top-level Non-Object, Non-Array Values¶
由过时的 RFC 4627指定的旧版本JSON要求JSON文本的顶级值必须是JSON对象或数组(Python dict
或list
),并且不能是JSON空值,布尔值,数字或字符串值。 RFC 7159删除了该限制,此模块不会,也从未在其序列化器或其解串器中实现此限制。
无论如何,为了实现最大的互操作性,您可能希望自愿遵守该限制。
19.2.4.5. Implementation Limitations¶
一些JSON解串器实现可能设置以下限制:
- 接受的JSON文本的大小
- JSON对象和数组的最大嵌套级别
- JSON数字的范围和精度
- JSON字符串的内容和最大长度
除了相关的Python数据类型本身或Python解释器本身之外,此模块不强加任何此类限制。
当序列化为JSON时,请注意可能会消耗您的JSON的应用程序中的任何此类限制。特别地,通常将JSON数字反序列化为IEEE 754双精度数字,并且因此服从于该表示的范围和精度限制。当序列化非常大的Python int
值或者序列化“异常”数值类型的实例(例如decimal.Decimal
)时,这一点尤其重要。
19.2.5. Command Line Interface¶
源代码: Lib / json / tool.py
json.tool
模块提供了一个简单的命令行界面来验证和美观打印JSON对象。
如果未指定可选的infile
和outfile
参数,将分别使用sys.stdin
和sys.stdout
:
$ echo '{"json": "obj"}' | python -m json.tool
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
在版本3.5中更改:输出现在与输入处于相同的顺序。使用--sort-keys
选项按字母顺序对字典的输出进行排序。
19.2.5.1. Command line options¶
-
infile
¶
要验证或打印的JSON文件:
$ python -m json.tool mp_films.json [ { "title": "And Now for Something Completely Different", "year": 1971 }, { "title": "Monty Python and the Holy Grail", "year": 1975 } ]
如果未指定infile,请从
sys.stdin
中读取。
-
outfile
¶
将infile的输出写入给定的outfile。否则,将其写入
sys.stdout
。
-
--sort-keys
¶
按字母顺序按字母顺序排序字典的输出。
版本3.5中的新功能。
-
-h
,
--help
¶
显示帮助消息。
脚注
[1] | 正如RFC 7159的勘误中所述,JSON允许字符串中的字面值U + 2028(LINE SEPARATOR)和U + 2029(PARAGRAPH SEPARATOR)字符,而JavaScript(ECMAScript Edition 5.1版) 。 |