序列化和反序列化以及json相关
序列化和反序列化
为什么要序列化
内存中的字典、列表、集合以及各种对象,如何保存到一个文件中?
如果是自己定义的类的实例,如何保存在一个文件中?
如何从文件中读取数据,并让他们在内存中再次回复称自己对应的类的实例?
要设计一套协议,按照某种规则进行转换,转换后的数据可以用来存储或者传输。文件是一个字节序列,所以必须把数据转换成字节序列(可以害死),输出到文件。这就是序列化。反之从文件的字节序列恢复到内存并且还是原来的类型,这就是反序列化。
序列化协议的特点
- 跨平台,并有多语言支持。这是根本目的。
- 足够流行,意味着使用者众多,协议的基础设施迭代更新快。
- 足够成熟,意味着协议经过足够的测试,和足够时间的检验。
- 语言/平台的中立性,意味着协议对各个编程语言、操作系统的特性支持保持一致。
- 可读性,如果数据序列化之后的数据人眼可读,那么开发过程对序列化数据的调试就会变得非常简单。
- 性能,为了保持原有的数据结构,数据在序列化的过程中,必然会加进额外的描述字段。加入额外的字段,必然会使序列化后的大小大于纯数据的大小,同时也会涉及到序列化、反序列化对描述字段的解读效率的问题。因此一个好的序列化协议,应该在空间复杂度和时间复杂度上有好的表现。
pickle库
python中的序列化、反序列化模块。
函数 | 说明 |
---|---|
dumps | 对象序列化为bytes对象 |
dump | 对象序列化到文件对象 |
loads | 从bytes对象反序列化 |
load | 对象反序列化,从文件读取数据 |
序列化应用
一般来说本地序列化的应用很少,大多数场景都使用在网络传输中。
将数据序列化通过网络传输到远程节点,远程服务器上的服务将接收到的数据反序列化后,就可以使用了。
但是要注意一点,远程接收端,反序列时必须要有对应的数据类型,否则就会报错。尤其是定义类 ,必须远程得有一直的定义。
现在大多数项目都不是单机的,也不是单服务的,需要多个程序之间配合,需要通过网络将数据传送到其他节点上去,这就是大量的序列化、反序列化过程。
JSON
JSON起源于弱类型语言javascript,他的产生来自一种称为"Associative array"的概念,其本质是就是采用"Attribute-value"的方式来描述对象。实际上在 Javascript 和 PHP 等弱类型语言中,类的描述方式就是 Associative array。JSON 的如下优点,使得它快速成为最广泛使用的序列化协议之一。
json的优点:
1.这种 Associative array 格式非常符合工程师对对象的理解。
2.它保持了 XML 的人眼可读(Human-readable)的优点。
3.相对于 XML 而言,序列化后的数据更加简洁。 来自于的以下链接的研究表明:XML 所产生序列化之后文件的大小接近 JSON 的两倍。http://www.codeproject.com/Articles/604720/JSON-vs-XML-Some-hard-numbers-about-verbosity
4.它具备 Javascript 的先天性支持,所以被广泛应用于 Web browser 的应用常景中,是 Ajax 的事实标准协议。
5.与 XML 相比,其协议比较简单,解析速度比较快。
6.松散的 Associative array 使得其具有良好的可扩展性和兼容性。
json模块
python支持少量内建数据类型到json类型的转换。
Python类型 | Json类型 |
---|---|
True | true |
False | false |
None | null |
string | string |
int | integer |
float | float |
list | array |
dict | object |
常用方法
Python类型 | Json类型 |
---|---|
dumps | json编码序列化为json格式的str |
dump | json编码序列化一个obj输出到一个file-like对象 |
loads | 将一个包含json文档的str、bytes或者bytearray反序列化为python对象 |
load | 将一个包含json文档的textfile或者binaryfile反序列化为一个python对象 |
json的典型应用场景
json在很多场景中都可以替代XML,更简洁并且解析速度更快
1.公司之间传输数据量较小,实时性要求较低的服务。
2.基于web browser的ajex
3.由于 JSON 具有非常强的前后兼容性,对于接口经常发生变化,并对可调式性要求高的场景,例如 Mobile app 与服务端的通讯。
4.由于 JSON 的典型应用场景是 JSON+HTTP,适合跨防火墙访问。总的来说,采用 JSON 进行序列化的额外空间开销比较大,对于大数据量服务或持久化,这意味着巨大的内存和磁盘开销,这种场景不适合。没有统一可用的 IDL 降低了对参与方的约束,实际操作中往往只能采用文档方式来进行约定,这可能会给调试带来一些不便,延长开发周期。 由于 JSON 在一些语言中的序列化和反序列化需要采用反射机制,所以在性能要求为 ms 级别,不建议使用。
MessagePack
MessagePack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。
他可以像json那样,在许多语言之间交换数据。
但是他比json更快速更轻巧。
它支持Python、Ruby、Java、C++等众多语言。
兼容json和pickle
常用方法
方法 | 含义 |
---|---|
packb | 序列化对象,提供了dumps来兼容pickle和json |
unpackb | 反序列化对象。提供了loads来兼容。 |
pack | 序列化对象到一个file-like对象,提供了dump来兼容。 |
unpack | 反序列化file-like对象,提供了load来兼容。 |
MessagePack简单易用,高效压缩,支持语言丰富。所以,用它序列化也是一种很好的选择。
Python很多大名鼎鼎的库都是用了msgpack
更多详细内容可以参考下面链接
序列化和反序列化
pickle模块官方文档
www.json.org
msgpack.org