在程序运行的过程中,所有的变量都是在内存中。一旦程序结束,变量所占用的内存就被操作系统全部回收。
为了避免数据丢失,把变量从内存中变成可存储或传输的过程称之为序列化
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化。
先用常规的方法将一个字典写入到文件中
info = {
'name':"zhang",
'age':22
}
with open('test.txt','w') as f:
#字典无法写入文件,必须转换成字符串
f.write(str(info))
执行程序,查看test.txt文件内容如下:
{'name': 'zhang', 'age': 22}
读取文件内容,加载到内存中,需要用到eval
eval() 将字符串str当成有效的表达式来求值并返回计算结果
with open('test.txt','r') as f:
data = eval(f.read())
print(data['name'])
执行输出 zhang
下面介绍 标准用法,用json模块
序列化:
import json
info = {
'name':"zhang",
'age':22
}
with open('test.txt','w') as f:
f.write(json.dumps(info))
#查看序列化之后的变量类型
print(type(json.dumps(info)))
执行输出 class 'str'
可以看到类型是字符串了。
反序列化:
import json
with open('test.txt','r') as f:
data = json.loads(f.read())
print(data['name'])
执行输出 zhang
json只能处理简单的数据类型,比如:字符串、字典、列表等
不支持函数,类 转换。
json主要用于不同语言之间数据交互
是目前主流的数据交互格式。
那么其他复杂的数据类型,要序列化,怎么办呢?用pickle
pickle,用于python特有的类型 和 python的数据类型间进行转换。
pickle的语法和json是一样的
序列化
import pickle
info = {
'name':"zhang",
'age':22
}
#因为pickle之后,类型是二进制,所以模式是wb
with open('test.txt','wb') as f:
f.write(pickle.dumps(info))
#查看序列化之后的变量类型
print(type(pickle.dumps(info)))
执行输出 class 'bytes'
反序列化
import pickle
with open('test.txt','rb') as f:
data = pickle.loads(f.read())
print(data['name'])
执行输出 zhang
注意:pickle的数据类型只有python能用,其他语言,比如java是不能识别的。
pickle代码优化
序列化
import pickle
info = {
'name':"zhang",
'age':22
}
with open('test.txt','wb') as f:
pickle.dump(info,f)
执行效果同上
pickle.dump(info,f) 就等同于 f.write(pickle.dumps(info))
反序列化
import pickle
with open('test.txt','rb') as f:
data = pickle.load(f)
print(data['name'])
执行效果同上
pickle.load(f) 等同于 pickle.loads(f.read())
举一个特殊例子
多次序列化
这里先序列化一次,修改年龄之后,再序列化一次
import json
info = {
'name':"zhang",
'age':22
}
with open('test.txt','w') as f:
json.dump(info,f)
info['age'] = 21
json.dump(info, f)
执行程序,查看test.txt内容
{"name": "zhang", "age": 22}{"name": "zhang", "age": 21}
反序列化
import json
with open('test.txt','r') as f:
data = json.load(f)
print(data['name'])
执行程序,报错
json.decoder.JSONDecodeError: Extra data: line 1 column 29 (char 28)
注意:在python 3.0版本中,一个文件只允许序列化一次。
举个场景,VMware Workstation软件可以创建多个快照,并且可以恢复到任意的快照。它是怎么做到的呢?就是每个快照,有独立的文件。
所以在python中,要想序列化多次,必须每次保存的文件是不一样的才行。