– JSON编码器和解码器 – 互联网数据处理(Python教程)(参考资料)
json
– JSON编码器和解码器
源代码: Lib / json / __ init__.py
JSON(JavaScript Object Notation),由 RFC 7159指定(废弃 RFC 4627 )和byECMA-404,是一种灵感来自JavaScript对象文字语法的轻量级数据交换格式(虽然它不是JavaScript的严格子集[1])。
json
公开了标准库用户熟悉的API marshal
和pickle
modules.
编写基本的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验证和漂亮打印:
$ echo "{"json":"obj"}" | python -m json.tool{ "json": "obj"}$ echo "{1.2:3.4}" | python -m json.toolExpecting property name enclosed in double quotes: line 1 column 2 (char 1)
请参阅命令行界面了解详细文档.
注意
JSON是YAML 1.2的子集。由此模块的默认设置(特别是默认值separators值)生成的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, default=None, sort_keys=False, **kw)-
序列化obj作为JSON格式化的流到fp(
.write()
– 支持类文件对象)使用这个转换表.如果skipkeys为真(默认值:
False
),那么dict键不是基本类型(str
,int
,float
,bool
,None
)将跳过而不是提出TypeError
.json
模块总是产生str
对象,而不是bytes
对象。因此,fp.write()
必须支持str
输入如果ensure_ascii为真(默认值),输出保证所有传入的非ASCII字符都被转义。如果ensure_ascii为false,这些字符将输出as-is.
如果check_circular为false(默认值:
True
),则对容器进行循环引用检查类型将被跳过,循环引用将导致OverflowError
(或更糟).如果allow_nan为假(默认:
True
),那么它将ValueError
严格按照JSON规范序列化超出范围float
values(nan
,inf
,-inf
)。如果allow_nan为真,则其JavaScript等效(NaN
,Infinity
,-Infinity
)将被使用如果indent是一个非负整数或字符串,然后JSON数组元素和对象成员将使用该缩进级别进行漂亮打印。缩进级别0,负数或
""
仅插入换行符。None
(默认值)选择最紧凑的表示。使用正整数缩进,每个级别有很多空格。如果indent是一个字符串(例如"\t"
),该字符串用于缩进每个级别.更改版本3.2:除了整数之外还允许indent的字符串.
如果指定的话,separators应该是
(item_separator, key_separator)
元组。默认是(", ", ": ")
如果indent是None
和(",", ": ")
除此以外。要获得最紧凑的JSON表示,您应该指定(",", ":")
消除空白.版本3.4更改:使用
(",", ": ")
如果indent不是None
.如果指定,default应该是一个被调用的对象,否则无法序列化。它应该返回一个JSON可编码的对象版本或者
TypeError
。如果没有指定,则TypeError
被引发如果sort_keys为真(默认:
False
),那么输出的数据将按键排序.使用自定义
JSONEncoder
子类(例如覆盖default()
序列化其他类型的方法),用cls kwarg指定;否则JSONEncoder
使用.更改版本3.6:所有可选参数现在仅限关键字.
注意
与
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, default=None, sort_keys=False, **kw )-
序列化obj到JSON格式
str
使用这个转换表。参数与中的含义相同dump()
.注意
JSON的键/值对中的键总是
str
。当字典转换为JSON时,字典的所有键都被转换为字符串。因此,如果将字典转换为JSON然后再转换为字典,则字典可能与原始字典不同。也就是说,loads(dumps(x)) != x
如果x有nonstringkeys.
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()
支持文本文件或包含JSON文档的二进制文件使用这个转换表到Python对象.object_hook是一个可选函数,将被调用任何对象文字的结果(
dict
)。将使用object_hook的返回值代替dict
。此功能可用于实现自定义解码器(例如JSON-RPCclass提示).object_pairs_hook是一个可选函数,将使用有序对列表解码的任何对象文字的结果调用。将使用object_pairs_hook的值来代替
dict
。此功能可用于实现自定义解码器。如果object_hook也定义,object_pairs_hook优先级.更改版本3.1:添加对object_pairs_hook.
parse_float的支持,如果指定,将使用要解码的每个JSONfloat的字符串调用。默认情况下,这相当于
float(num_str)
。这可以用来为JSON浮点数使用另一种数据类型或解析器(例如decimal.Decimal
).parse_int如果指定,将使用每个要解码的JSON的字符串调用。默认情况下,这相当于
int(num_str)
。这可以用于为JSON整数使用另一种数据类型或解析器(例如float
).parse_constant,如果指定,将使用以下一个字符串调用:
"-Infinity"
,"Infinity"
,"NaN"
。如果遇到无效的JSON号码,这可用于引发异常.改变版本3.1:parse_constant不再调用’null’,’true’,’false’。
使用自定义的
JSONDecoder
子类,用cls
kwarg指定它;除此以外JSONDecoder
用来。其他关键字参数将被传递给类的构造函数.如果被反序列化的数据不是有效的JSON文档,则
JSONDecodeError
将被引发在版本3.6中更改:所有可选参数现在都是仅限关键字.
在版本3.6中更改:fp现在可以是二进制文件。输入编码应为UTF-8,UTF-16或UTF-32.
json.
loads
(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)-
Deserialize s(a
str
,bytes
或bytearray
包含JSON文档的实例)使用这个转换表.其他参数与
load()
中的含义相同,除了encoding被忽略和弃用.如果被反序列化的数据不是有效的JSON文档,//
JSONDecodeError
会被举起来版本3.6更改:s现在可以是
bytes
要么bytearray
。输入编码应为UTF-8,UTF-16或UTF-32 .
编码器和解码器
- class
json.
JSONDecoder
(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None) -
简单的JSON解码器
默认情况下在解码时执行以下翻译:
JSON Python object dict array list string str number(int) int number(real) 浮 真正 真 假 假 null 没有 它也理解
NaN
,Infinity
和-Infinity
作为对应的float
值,这超出了JSON规范object_hook,如果指定,将调用每个JSONobject解码的结果,并使用其返回值代替给定的
dict
。这可用于提供自定义反序列化(例如,支持JSON-RPC类提示).object_pairs_hook,如果指定将使用有序的对列表对解析的everyJSON对象的结果进行调用。将使用object_pairs_hook的返回值代替
dict
。此功能可用于实现自定义解码器。如果object_hook是alsodefined,则object_pairs_hook优先.在版本3.1中更改:添加对object_pairs_hook.
parse_float的支持,如果指定,将使用要解码的每个JSONfloat的字符串调用。默认情况下,这相当于
float(num_str)
。这可以用来为JSON浮点数使用另一种数据类型或解析器(例如decimal.Decimal
).parse_int如果指定,将使用每个要解码的JSON的字符串调用。默认情况下,这相当于
int(num_str)
。这可以用来为JSON整数使用另一个数据类型或解析器(例如float
).parse_constant,如果指定,将使用以下一个字符串调用:
"-Infinity"
,"Infinity"
,"NaN"
。这可以如果遇到无效的JSON号,则用于引发异常.如果strict为false(
True
是默认值),则控制字符将被允许在字符串内。此上下文中的控制字符包含0-31范围内的字符代码,包括"\t"
(tab),"\n"
,"\r"
和"\0"
.如果要反序列化的数据不是有效的JSON文件,一个
JSONDecodeError
将被抬起.在版本3.6中更改:现在所有参数都是仅关键字.
decode
(s)-
返回s的Python表示(
str
包含JSON文档的实例).JSONDecodeError
如果给定的话会被提出JSON文件无效.
raw_decode
(s)-
从s(
str
从aJSON文档开始)并返回Python表示的2元组和s中文档结束的索引.这可以用于从可能具有extraneous的字符串中解码JSON文档最后的数据.
- 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 dict object list,tuple array str string int,float,int-&float-derived Enums number True true False false 没有 null 在版本3.4中更改:添加了对int和float派生的Enum类的支持.
扩展它以识别其他对象,子类并实现一个
default()
方法用另一个方法返回一个可序列化的对象o
如果可能的话,否则它应该调用超类实现(提升TypeError
).如果skipkeys是假的(默认),那就是
TypeError
尝试编码不是str
,int
,float
或None
的密钥。如果skipkeys为真,那么这些项目就是简单的.如果ensure_ascii为真(默认值),输出将保证所有传入的非ASCII字符都被转义。如果ensure_ascii是错误的,这些字符将输出as-is.
如果check_circular为true(默认值),则将检查列表,dicts和customencoded对象编码过程中的循环引用可以防止无限递归(这会导致
OverflowError
)。否则,不会发生这样的检查.如果allow_nan为真(默认值),那么
NaN
,Infinity
和-Infinity
将被编码。此行为不符合JSON规范,但与大多数JavaScript basedencoders和解码器一致。否则,ValueError
会对这些浮点数进行编码如果sort_keys为真(默认:
False
),那么字典的输出将按以下顺序排序键;这对于回归测试很有用,可以确保日常比较JSON序列化.如果indent是一个非负整数或字符串,然后JSON数组元素和对象成员将使用该缩进级别进行漂亮打印。缩进级别0,负数或
""
仅插入换行符。None
(默认值)选择最紧凑的表示。使用正整数缩进,每个级别有很多空格。如果indent是一个字符串(例如"\t"
),该字符串用于缩进每个级别.更改版本3.2:除了整数之外还允许indent的字符串.
如果指定的话,separators应该是
(item_separator, key_separator)
元组。默认是(", ", ": ")
如果indent是None
和(",", ": ")
除此以外。要获得最紧凑的JSON表示,您应该指定(",", ":")
消除空白.版本3.4更改:使用
(",", ": ")
如果indent不是None
.如果指定,default应该是一个被调用的对象,否则无法序列化。它应该返回一个JSON可编码的对象版本或者
TypeError
。如果没有指定,则TypeError
被提升.更改版本3.6:所有参数现在都是 keyword-only .
default
(o)-
在子类中实现此方法,使其返回o的serializable对象,或调用基本实现(以提升
TypeError
).例如,为了支持任意迭代器,你可以实现defaultlike:
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数据结构的JSON字符串表示,o。例如:
>>> json.JSONEncoder().encode({"foo": ["bar", "baz"]})"{"foo": ["bar", "baz"]}"
iterencode
(o)-
对给定对象进行编码,o,并将每个字符串表示形式为可用。例如:
for chunk in json.JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
异常
- exception
json.
JSONDecodeError
(msg, doc, pos) -
ValueError
的子类,具有以下附加属性:msg
-
未格式化的错误消息.
doc
-
正在解析的JSON文档.
pos
-
的起始索引doc解析失败的地方.
lineno
-
对应pos.
colno
-
对应于的列pos.
版本3.5中的新功能.
标准兼容性和互操作性
JSON格式由 RFC 7159 通过ECMA-404。本节详细介绍了该模块与RFC的兼容程度。为简单起见,JSONEncoder
和JSONDecoder
除了那些明确提到的参数之外,不考虑子类和参数.
此模块不严格遵守RFC,实现了一些有效JavaScript但不是有效JSON的扩展。特别是:
- 接受并输出无限和NaN数值;
- 接受对象中的重复名称,并且仅使用lastname-value对的值.
由于RFC允许符合RFC的解析器接受不符合RFC的输入文本,因此该模块的解串器在技术上符合RFC的默认设置.
字符编码
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反序列化器忽略其输入中的initialBOM。这个模块的解串器引发了ValueError
当初始BOM存在时
RFC没有明确禁止包含与有效Unicode字符不对应的字节序列的JSON字符串(例如,未配对的UTF-16surrogates),但它确实注意到它们可能会导致互操作性问题。默认情况下,此模块接受并输出(如果存在)在原来的str
)这些序列的代码点.
无限和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 参数可用于改变此行为.
在对象内重复的名称
RFC指定其中的名称JSON对象应该是唯一的,但不要求如何处理JSON对象中的重复名称。默认情况下,此模块不会引发异常;相反,它会忽略除给定名称的最后一个名称 – 值对之外的所有名称:
>>> weird_json = "{"x": 1, "x": 2, "x": 3}">>> json.loads(weird_json){"x": 3}
命令行界面
时,这尤其相关源代码: 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.toolExpecting property name enclosed in double quotes: line 1 column 2 (char 1)
在版本3.5中更改:输出现在与输入的顺序相同。使用--sort-keys
选项按键按字母顺序对字典输出进行排序。
命令行选项
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
-
显示帮助信息
Footnotes
[1] | 如RFC 7159的勘误表中所述,JSON允许在字符串中使用文字U + 2028(LINE SEPARATOR)和U + 2029(PARAGRAPH SEPARATOR)字符,而JavaScript(从ECMAScript版本5.1开始)则不允许. |
评论被关闭。