序列化反序列化
1.为什么要反序列化?什么是序列化?
1.1定义
seralization 序列化
将内存中对象存储下来,把它变成一个一个的字节.(数据解构–>二进制)
deserializtion 反序列化
将文件恢复成一个一个的内存中的对象.二进制—>数据结构
1.2为什么要反序列化和序列化?
内存中的字典,列表,集合,以及各种对象如何保存到一个文件中?
如果是自己定义的类实例,如何保存到一个文件中?
如何从文件中读取数据?并让他们在内存中再次恢复成自己对应的类实例?
遵循一套协议,按照某种规则,把内存中的数据保存到文件中,文件是一个字节序列化,所以必须把数据转换成字节序列,输出到文件,这就是序列化.
反之 将文件中的字节恢复到内存并且还是原来的类型,则就是反序列化.
1.3 pickle
pickle的序列化反序列化
函数 | 说明 |
---|---|
dumps | 对象序列化为bytes对象 |
dump | 对象序列化为文件对象,就是存入文件 |
loads | 从bytes对象反序列化 |
load | 对象反序列化,从文件读取数据 |
import pickle
filename = 'd:/python/test.txt'
a = 1
b = 'i'
c = list('123')
d = { a : '123', 'b' : 'abc' , 'c' : [1,2,3] }
with open(filename,'wb') as f :
pickle.dump(a,f)
pickle.dump(b,f)
pickle.dump(c,f)
pickle.dump(d,f)
with open(filename,'rb') as f :
print (f.read(),f.seek(0))
for i in range(4) :
x = pickle.load(f)
print (i,x,type(x))
1.4 序列化应用
一般来说本地序列化应用,应用比较少,一般都应用在网络应用中,
将数据序列化之后通过网络传输到远程节点,远程服务器上的服务将接收到数据反序列化,就可以使用了.
需要注意一点,远程接受端,反序列化是必须有对应的类型数据,否则就会报错,尤其是自定义类,必须有明确的定义.
python之间可以使用pickle解决序列化和反序列化,如果是跨平台,跨语言,跨协议,pickle是不合适了,需要公共协议比如XML,JSON,Protocol buffer,magpack
针对不同协议,效率不同,学期曲线不同,适用不同场景,根据不同情况分析.
注:目前6个版本pickle协议,3.4增加v4.3.8增加了v5
JSON
JSON(Java Script Object Notation , JS 对象标记) 是一种轻量级数据交换格式,基于ECMAScript 1999年的ES3的一个子集,采用完全独立编辑语言的文本格式来存储和表示.
JSON的数据类型
值
双引导引起来的字符串,数值,true和false,null,对象,数组,这些都是值
Value —>string
—>number
—>object
—>array
—>true
—>false
—>null
字符串
由双引导包围起来的任意字符的组合,可以有转义符
数值
有正数,有负数,浮点数
对象
无序的键值对的集合
格式:{key1:value1……}
key必须是一个字符串,需要双引导包围这个字符串
value可以是任何合法的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWOC234E-1653876538522)(C:\Users\Administrator.DESKTOP-TNPJOM3\AppData\Roaming\Typora\typora-user-images\image-20220528090708933.png)]
数组
有序的值的集合
格式:[val1 ….,vlan]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUyvlR2v-1653876538525)(C:\Users\Administrator.DESKTOP-TNPJOM3\AppData\Roaming\Typora\typora-user-images\image-20220528090809604.png)]
实例
{
"images":[
{
"name":'liuliuliu',
"tag":"v1"
},
{
"name":"hoame",
"tag":12
}
],
"total":2
}
python支持少量内建数据类型到json类型的转换
python类型 | Json类型 | 说明 |
---|---|---|
True | true | |
False | false | |
None | null | |
str | string | |
int | integer | |
float | float | |
list | array | 数组 |
dict | object | 对象 |
常用方法
python 类型 | Json类型 |
---|---|
dumps | json编码 |
dump | json编码并且存入文件 |
loads | json编码 |
load | json编码并且存入数据 |
import json
filename = 'd:/python/test.txt'
d = {'name':'xiaohong','age':'12','interest':('music','move'),'class':['python']}
j = json.dumps(d) #写入到文件--->字符串
print (j,type(j))
with open(filename,'w+') as f : #使用with 写入到文件
f.write(j)
dd = json.loads(j) #将str文件 --->内存 注意字符类型
print (dd,type(dd))
print (dd == d )
print (dd is d)
一般来说json数据很难落地,都是用于网络传输,但是传输的都是字符串所以需要压缩一下减少网络带宽.
本质上说json就是一个文本,str.
json很简单,几乎所有语言都支持json,所以应用广泛.
MessagePack
messagepack 类似一个二进制高效的对象序列化类库,可用于跨语言通信.
多种语言的交换解构对象
但是比json更加的快速轻巧.
支持 python ruby,java,c/c++等语言.宣称比google protocol buffers 还要快四倍
兼容json和pickle.
import pickle
import json
import msgpack
methods = (pickle,json,msgpack)
d = {'name':'xiaohong','age':'12','interest':('music','move'),'class':['python']}
for m in methods:
s = m.dumps(d)
print (m.__name__,s,type(s),len(s),sep='\n')
#pickle 93b
#json 85
#msgpack 57
u =msgpack.loads(s)
print (u,type(u))
u2 = msgpack.loads(s,raw=False)
print (u2,type(u2))