1. 什么是序列化
有时候,我们希望存储或者传输不只是数据,而是一些内存中的对象和数据结构,以便在远程或者其他进程中可以直接使用相同的对象。
常见的场景有,在数据分析过程中,通常模型训练是离线的,而预测时线上的,而同时也需要不断的更新模型到线上来预测;所以当我们训练好一个机器学习的模型时需要保存这个模型的内存中对象(包括上下文的状态信息),以便可以用来做预测;在分布式计算时,如spark内存分布式计算框架,在集群之间需要进行大量的对象传输;
这里的将内存中对象存储的过程就是序列化,而在其他进程中使用这个对象的过程是反序列化。
更简单的说,序列化就是把内存中的数据结构在不丢失其身份和类型信息的情况下转成对象的文本或二进制表示的过程。而反序列化就是将对象的文本或者二进制还原成原始对象的过程。
2. python的序列化
python中提供需要方法支持序列化,比较常用的pickle和json
其中序列化的过程是dump,反序列化的过程是load
我们来看看
import pickle
dict_obj = {"name": "jack", "age": 40}
with open('picklefile.data', 'wb') as f:
pickle.dump(dict_obj, f)
print(dict_obj, type(dict_obj))
# {'name': 'jack', 'age': 40} <class 'dict'>
with open('picklefile.data', 'rb') as f:
new_dict_obj = pickle.load(f)
# {'name': 'jack', 'age': 40} <class 'dict'>
pickle几乎支持python所有的对象,包括布尔、数字、字符串、字节数组、None、列表、元组、字典和集合等基本数据类型,picike还能够处理循环,递归引用对象、类、函数以及类的实例等
pickle有一个C的实现即Cpickle,区别就是速度,Cpickle的速度是pickle的1000倍import cPickle as pickle
3.python序列化的缺点
- 首先pickle是python的包,pickle序列化对象只能在python环境中使用,不能跨语言
- pickle可能存在安全性问题
跨语言的问题,Java序列化同样的问题。通用的有google的Protocol Buffers和facebook的Thrift,有兴趣可以了解下,包括gRPC。