python 序列化
1 字符串的存储
此前,我们是怎么实现一个字典的本地存储的?
我们先将字典用str()转换成字符串,再存到磁盘。使用的时候,取出来,再用eval()将字符串转换成字典。
但这样做有很大的局限性,如果要将本地化的字符串给其他编程语言使用就不行了。这个时候就需要序列化与反序列号。
序列化就相当于str()的过程,反序列号就相当于eval()。
2 序列化
我们把变量从内存变成可存储或传输的过程称为序列化,在python中叫pickling,其他语言叫serialization、marshalling、flattening 等等。
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器。
反之,把变量内容从序列化对象重新读入到内存的过程叫反序列号,即unpickling。
python中有两个序列化模块,pickle和json
1 json
json序列化后产生的json字符串,是JavaScript里面对应的一种数据类型。所以,json序列化以后,能被其他编程语言识别。JSON 不仅是标准格式,并且比 XML 更快,而且可以直接在 Web 页面中读取,非常方便。JSON 表示的对象就是标准的 JavaScript 语言的对象。
Json模块提供了四个功能:dumps、dump、loads、load
- 将字符串序列化和反序列号
import json
s=['a','b']
res=json.dumps(s)
print(res)
print(type(res))
结果:
"[a,b]"
<class 'str'>
返回的是json字符串
print(json.loads(res)[0])
结果:
a
- 序列化字符串到本地文件,和文件中的字符串反序列化
f=open("json.txt","w+",encoding="utf-8")
f.write(json.dumps(s))
f.seek(0)
print(json.loads(f.read())[1])
f.close()
结果:
b
使用dump和load则无需手动开启文件
json.dump(s,f)
f.seek(0)
print(json.load(f)[0])
结果:
a
dump(),将字符串序列换到文件,光标也会移动到最后。需要先seek,在读取。
- 补充
在上述实验中,json.txt中存储的就是json字符串。
我们修改json.txt中的字符串:
{"a":1,"b":2}
代码部分:
with open("json.txt","r") as f_read:
print(json.load(f_read)["b"])
结果:
2
实际上,json类型与python类型有一个映射关系,只要按照映射关系来书写字符串,是可以用json反序列化的。
如果我们把json.txt修改为:
{"name":"元"}
#UnicodeDecodeError: 'gbk' codec can't decode byte 0x83 in position 11: illegal multibyte sequence
此时会报错,因为json反序列号时,默认的是以系统默认的编码来解码的。在文件句柄中添加encoding="utf-8"即可。
2 pickle
pickle序列化成只有python能识别的数据类型,并且可能不同版本的 Python彼此都不兼容,所以pickle可以用来保存那些不怎么重要的数据。
pickle模块提供了四个功能:dumps、dump、loads、load
使用方式和json一样。
将字典d序列化,使用pickle.dumps(d)
import pickle
d=dict(name="bob",age=20)
print(pickle.dumps(d))
结果:
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00bobq\x02X\x03\x00\x00\x00ageq\x03K\x14u.'
pickle序列化的特点:
- 将数据处理成字节
- 由于是python内置的,所以可以序列化python中的任意数据类型
将字典序列化到文件pickle.dump(d,f)
f=open("dump.txt","wb")
pickle.dump(d,f)
f.close()
序列化以后,是乱码,不是utf-8也不是gbk,是一种只有python能识别的编码。
f=open("dump.txt","rb")
print(pickle.load(f))
f.close()
结果:
{'name': 'bob', 'age': 20}