首页 > 技术文章 > 序列化和反序列化

spidermansam 2017-10-30 19:25 原文

思考:
 
为什么要使用序列化?
使用序列化之后,就可以将序列化后的内容写入磁盘,或者通过网络传输到别的机器上
 
为什么要使用反序列化?
一个文件序列化之后是不方便使用者对其进行查看或者修改的,所以使用反序列化,可以还原他未序列化时的文件模型
将变量内容从序列化的对象重新读取到内存里称之为反序列化
 
 
pickle使用时需要注意,发送和接收方的pickle版本可能不一致,从而导致序列化的出来的文件也不一致
使用pickle操作时,用什么方法写入,就必须用什么方法读取(dump,load)(dumps,loads) 
pickle库
dumps 对象序列化
dump 对象序列化到文件对象(存入文件)
loads 对象反序列化     
load 对象反序列化,从文件中读取数据
 
使用模块pickle对一个文件或者数据类型进行序列化:
举例:
import pickle
d = dict(name = Bob , age = 20 , Score =88)
pickle.dumps(d)
返回结果为:
b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'
pickle.dumps()方法把任意序列对象序列化为一个bytes,然后可以将这个bytes写入文件,或者
 
举例:
with open( 'I:/readme.txt', 'wb' )as f :
     pickle.dump(需要保存的数据或文件,被保存的实体对象)
     pickle.dump(d , f)  
pickle.dump()直接把一个对象序列化后写入一个类文件对象中!
查看写入硬盘的文件,是一对二进制数据,不便于查看,这就是python序列化后的内部信息
 
当我们要把对象从磁盘读到内存中时,可以先把内容读到一个bytes中,再用pickle.loads()反序列化出对象,也可以使用pickle.load()方法从一个类文件对象中,直接反序列化出对象
举例:
with open('I:/readme.txt', 'rb' ) as f :
     pickle.load( f )
     print(f)
会显示:
{'age': 20, 'score': 88, 'name': 'Bob'}
 
这个变量和原来的变量是完全不相干的对象,只是他们的内容相同而已 
pickle的问题和其他编程语言特有的序列化问题一样,只能用于python中,不能跨语言,版本使用,所以只能用pickle保存一些补重要的数据,即便不能成功的反序列化也没有关系
 
可调式性/可读性

可调试性/可读性

序列化和反序列化的数据正确性和业务正确性的调试往往需要很长的时间,良好的调试机制会大大提高开发效率。序列化后的二进制串往往不具备人眼可读性,为了验证序列化结果的正确性,写入方不得同时撰写反序列化程序,或提供一个查询平台--这比较费时;另一方面,如果读取方未能成功实现反序列化,这将给问题查找带来了很大的挑战--难以定位是由于自身的反序列化程序的bug所导致还是由于写入方序列化后的错误数据所导致。对于跨公司间的调试,由于以下原因,问题会显得更严重。

  1. 支持不到位,跨公司调试在问题出现后可能得不到及时的支持,这大大延长了调试周期。
  2. 访问限制,调试阶段的查询平台未必对外公开,这增加了读取方的验证难度。
如果序列化后的数据人眼可读,这将大大提高调试效率, XML和JSON就具有人眼可读的优点。
 
Json
js对象标记,是一种基于ECMAscript的一个子集,采用完全独立于编程语言的文本格式来村粗和表示数据的一种轻量化级的数据交换格式
 
jason的数据类型
值: 双引号引起来的字符串,数值,true和fales,null,对象,数组,这些都是值
字符串: 由双引号包围起来的任意字符的组合,可以有转义字符
数值: 有正负,有整数,浮点数
对象: 无序键值对的集合{k,v.......k,v},key必须是一个字符串,value可以是任意的值
数组:
有序的值的集合
格式[val1......valn]
json模块
python至此少量内建数据类型到json类型的转换
常用方法:
dumps json 编码
dupm json 编码并存入文件
 
loads json     解码
load json     解码,从文件中读取数据
 
jason编码的数据很少落地,数据都是通过网络传输, 传输的时候,要考虑压缩
本质上来说他就是个文本,是一个字符串,所以他的应用范围及其广泛
 
 
MessagepackPack
基于二进制搞笑的对象序列化类库,可用于跨语言通信
兼容json和pickle,比json更快速,更轻巧
原理:将一些可以替代的变量名,用ascii码来替代,从而大大的减少空间占用
 
安装:
使用pip安装:
pip install msgpack-python
 
使用方法:
packb 序列化对象,提供了dumps 来兼容json和pickle
unpackb 反序列化对象,提供了loads来兼容json和pickle
 
pack序列化对象并保存到文件对象,提供了dump来兼容
unpack 反序列化对象保存到文件对象,提供了load来兼容
 
MessgePack简单易用,且高效压缩,支持的语言也很多,也是一种序列化可选的方法
 

推荐阅读