一般的场景是这样:
标准的json(接口返回的) ==>(需要转换成) Python字典, 用json.loads
python字典格式 ==>(需要转换成) 标准的json, 用json.dumps
Python处理json的函数有四个:dumps、dump、loads、load
dumps
源码定义如下:
1
2
3
4
5
|
def 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):
"""Serialize ``obj`` to a JSON formatted ``str``.
....
|
注释Serialize ``obj`` to a JSON formatted ``str
说明了该函数的作用: 将obj序列化为str类型的JSON格式。
dumps至少接收一个obj参数,obj是什么呢,就是dict、list、tuple、str等这些python的数据类型。
比如我定义一个dict类型的obj
1
2
3
4
5
6
7
8
|
obj = {
"msgtype": "markdown",
"markdown": {
"title": "title",
"value": 0,
"text": None
}
}
|
注意,这是一个python的字典(dict)类型,所以只有python知道怎么处理。如果想让HTTP直接以POST方式处理,肯定是不行的(但像requests库有内置的 JSON解码器,所以可以直接帮你处理),需要先转换成HTTP能够理解的格式,即json。
使用json.dumps(obj)后,就会变成标准的json格式了。但是注意,json.dumps(obj)本身是str类型。
1
2
3
4
5
6
7
8
|
obj_to_json = json.dumps(obj)
print(obj_to_json)
print(type(obj_to_json))
#输出
{"msgtype": "markdown", "markdown": {"title": "title", "value": 0, "text": null}}
<class 'str'>
|
所以dumps的使用场景可以理解为当自己需要构造一个json时使用。
dump
源码定义如下:
1
2
3
4
5
6
|
def 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):
"""Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
``.write()``-supporting file-like object).
...
|
dump和dumps作用是一样的,只不过dump是必须要将序列化的结果保存到IO类的对象里。
1
2
3
4
5
6
7
8
9
10
|
# 序列化并保存到文件
with open('obj.txt', 'w') as f:
json.dump(obj, f)
# 读取结果
with open('obj.txt', 'r') as f:
print(f.read())
#输出
{"msgtype": "markdown", "markdown": {"title": "title", "value": 0, "text": null}}
|
注意obj是字典类型,所以当用load反序列化后的结果还是字典。
loads
源码定义如下:
1
2
3
4
|
def 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`` or ``bytearray`` instance
containing a JSON document) to a Python object.
|
当你从http地址(比如腾讯云api)请求一个地址后,对方都会返回一个response,基本都是json数据(注意是str类型,相应的SDK里会有转换的方法)。如腾讯云的安全组下的某个api返回的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
{
"SecurityGroupSet":[
{
"SecurityGroupId":"sg-5u9jj0ec",
"SecurityGroupName":"default",
"SecurityGroupDesc":"System created security group",
"ProjectId":"0","ALL",
"IsDefault":true,
"CreatedTime":"2021-01-07 15:54:13","ALL",
"TagSet":[
]
}
],
"TotalCount":1,
"RequestId":"284a79dd-8ef7-4d6e-936d-c9f7a5edc1b1","ALL"
}
|
这是print后的结果,实际的代码是resp.to_json_string(),使用loads函数获取某个字段的值(比如’CreatedTime’)如下:
1
2
3
4
5
|
resp_str = resp.to_json_string()
resp_dict = json.loads(resp_str)
print(resp_dict['SecurityGroupSet'][0]['CreatedTime'])
|
所以总结loads的使用场景是用于处理HTTP地址返回的json数据,转换为Python更具体的对象后(一般都是dict),Python就可以灵活处理了。
load
源码定义如下:
1
2
3
4
5
6
7
8
9
10
11
|
def 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.
....省略
"""
return loads(fp.read(),
cls=cls, object_hook=object_hook,
parse_float=parse_float, parse_int=parse_int,
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
|
读取一个文件,然后反序列化为python对象
比如,反序列化上面dump的例子
1
2
3
4
5
|
with open('obj.txt', 'r') as f:
print(json.load(f))
with open('obj.txt', 'r') as f:
print(type(json.load(f)))
|