0 前言
如果要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
1 什么是JSON?
- JSON(JavaScript Object Notation,JS 对象简谱) 是一种轻量级的数据交换格式,易于人阅读和编写。
- 并且,JSON还定死了字符集必须是UTF-8,表示多语言就没有问题了。为了统一解析,JSON的字符串规定必须用双引号
""
,Object的键也必须用双引号""
。- 把任何Python对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。
- 如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个Python对象,就可以在Python中直接使用这个对象了。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
JSON类型 |
Python类型 |
---|---|
{} | dict |
[] | list |
"string" | str |
1234.56 | int 或 float |
true / false | True / False |
null | None |
2 json模块常用的功能
Python内置的 json 模块提供了非常完善的 Python 对象到 JSON 格式的转换。我们一起看看如何在Python对象和JSON对象之间进行转换。
在使用json这个模块前,首先要导入json库
import json
方法 | 描述 | 简单记忆 |
---|---|---|
json.dumps() | 将 Python 对象编码成 JSON 字符串 | python对象 --> json字符串 |
json.dump() | 将 Python 内置类型序列化为 JSON 对象后写入文件 | python对象 --> 文件流 |
json.loads() | 将已编码的 JSON 数据解码为 Python 对象 | json字符串 --> python对象 |
json.load() | 读取文件中 JSON 形式的字符串元素转化为 Python 类型 | 文件流 --> python对象 |
2.1 json.dumps(obj) — 进行序列化
- obj:表示是要序列化的对象。
特点:将数字、列表、元组、字典等数据类型格式化为字符串(集合不能被序列化),这样可以方便别的编程语言进行调用。所有key必须都是字符串(强行转,易失真)。
代码如下:
ja=json.dumps(a)
jb=json.dumps(b)
jc=json.dumps(c)
jd=json.dumps(d)
je=json.dumps(e)
#jf=json.dumps(f) —— 集合不能被json序列化;会报TypeError类型的错误
jg1=json.dumps(g1)
jg2=json.dumps(g2)
print(ja,type(ja))
print(jb,type(jb))
print(jc,type(jc))
print(jd,type(jd))
print(je,type(je))
print(jg1,type(jg1))
print(jg2,type(jg2))
运行结果:
123 <class 'str'>
1.23 <class 'str'>
"123" <class 'str'>
[1, 2, 3] <class 'str'>
[1, 2, 3] <class 'str'>
{"1": 2, "3": 4} <class 'str'> #字典中所有key必须为字符串(强行转,易失真)
{"name": "adv", "age": 20} <class 'str'> #在这里我们可以看到,原先字典里的单引号变成双引号了
2.2 json.loads(s) — 进行反序列化
- s:将s(包含JSON文档的str,bytes或bytearray实例)反序列化为Python对象。
从下面的例子可以看到,先对python的一些基本类型序列化(dump)之后,全部变成了字符串类型;然后对其再进行反序列化(loads),tuple 类型就转成了 list 类型。
nja=json.loads(ja)
njb=json.loads(jb)
njc=json.loads(jc)
njd=json.loads(jd)
nje=json.loads(je)
njg1=json.loads(jg1)
njg2=json.loads(jg2)
print(nja,type(nja))
print(njb,type(njb))
print(njc,type(njc))
print(njd,type(njd))
print(nje,type(nje))
print(njg1,type(njg1))
print(njg2,type(njg2))
运行结果:
123 <class 'int'>
1.23 <class 'float'>
123 <class 'str'>
[1, 2, 3] <class 'list'> #元组被转换成列表
[1, 2, 3] <class 'list'>
{'1': 2, '3': 4} <class 'dict'> #字典中所有key必须为字符串(强行转,易失真)
{'name': 'adv', 'age': 20} <class 'dict'>
2.3 json.dump(obj , fp) — 把Python数据类型obj(除了集合)序列化进入一个文件fp中,等待别的程序进行调用。
- obj:表示是要序列化的对象。
fp:
文件描述符,将序列化的str保存到文件中。
with open("f1","w") as f:
json.dump(a,f)
with open("f2","w") as f:
json.dump(b,f)
with open("f3","w") as f:
json.dump(c,f)
with open("f4","w") as f:
json.dump(d,f)
with open("f5","w") as f:
json.dump(e,f)
'''with open("f6","w") as f: —— 集合不能被json序列化;会报TypeError类型的错误
json.dump(f,f)'''
with open("f7","w") as f:
json.dump(g1,f)
with open("f8","w") as f:
json.dump(g2,f)
运行完上面的代码,打开所在文件夹,可以看到名为f1、f2、f3、f4、f5、f7、f8的文件,分别打开它们,其内容为:
f1:123
f2:1.23
f3:"123"
f4:[1, 2, 3]
f5:[1, 2, 3]
f7:{"1": 2, "3": 4}
f8:{"name": "adv", "age": 20}
2.4 json.load(fp) — 读取文件fp中的内容。
fp:
文件描述符,将fp(.read()支持包含JSON文档的文本文件或二进制文件)反序列化为Python对象。
with open("f1") as f:
r1=json.load(f)
print(r1,type(r1))
with open("f2") as f:
r2=json.load(f)
print(r2,type(r2))
with open("f3") as f:
r3=json.load(f)
print(r3,type(r3))
with open("f4") as f:
r4=json.load(f)
print(r4,type(r4))
with open("f5") as f:
r5=json.load(f)
print(r5,type(r5))
with open("f7") as f:
r7=json.load(f)
print(r7,type(r7))
with open("f8") as f:
r8=json.load(f)
print(r8,type(r8))
打印反序列化后的数据及其类型,得到的结果为:
123 <class 'int'>
1.23 <class 'float'>
123 <class 'str'>
[1, 2, 3] <class 'list'> #元组被转换成列表
[1, 2, 3] <class 'list'>
{'1': 2, '3': 4} <class 'dict'> #字典中所有key必须为字符串(强行转,易失真)
{'name': 'adv', 'age': 20} <class 'dict'>