python学习之 ---序列化与反序列化+pickle库+Json序列化+MessagePack序列化
序列化与反序列化
为什么要序列化
内存中的字典、列表、集合以及各种对象,如何保存到一个文件中?
如果是自己定义的类的实例,如何保存到一个文件中?
如何从文件中读取数据,并让它们在内存中再次恢复成自己对应的类的实例?
要设计一套协议,按照某种规则,把内存中数据保存到文件中。文件是一个字节序列,所以必须把数据转换成字节
序列,输出到文件。这就是序列化。反之,从文件的字节序列恢复到内存并且还是原来的类型,就是反序列化。
定义
serialization
序列化
将内存中对象存储下来,把它变成一个个字节。–> 二进制
deserialization 反序列化
将文件的一个个字节恢复成内存中对象。<- -二进制
序列化保存到文件就是持久化。
可以将数据序列化后持久化,或者网络传输;也可以将从文件中或者网络接收到的字节序列反序列化。
Python 提供了pickle 库。
pickle库
函数 | 说明 |
---|---|
dumps | 对象序列化为bytes对象 |
dump | 对象序列化到文件对象,就是存入文件 |
loads | 从bytes对象反序列化 |
load | 对象反序列化,从文件读取数据 |
序列化
import pickle
a = 99
b = 'c'
c = [48,'abc']
d = {'a':'ddd','b':1}
with open('d:/tmp/ser','wb+')as f :
pickle.dump(a,f)
pickle.dump(b,f)
pickle.dump(c,f)
pickle.dump(d,f)
#反序列化
with open('d:/tmp/ser','rb')as f:
for i in range(4):#序列化几次就重复几次
x = pickle.load(f) # pickle.load 方法
print(type(x),x)
if isinstance(x,list): # 序列后的不是同一个内容了
print(id(x),id(c))
>>>
<class 'int'> 99
<class 'str'> c
<class 'list'> [48, 'abc']
2279579723848 2279579536904
<class 'dict'> {'a': 'ddd', 'b': 1}
对类文件进行序列化操作
import pickle
# 对象序列化
class AAA:
tttt = 'ABC'
def show(self):
print('abc')
a1 = AAA() # 创建AAA类的对象
# 序列化
ser = pickle.dumps(a1) # 类文件序列化用pickle.dumps
print('ser={}'.format(ser)) # AAA
# 反序列化
a2 = pickle.loads(ser)
print(a2.tttt)
a2.show()
# 序列化过程中仅把类对象名给序列化,并没有改变函数内部数据
上面的例子中,故意使用了连续的AAA、ABC、abc等字符串,就是为了在二进制文件中能容易的发现它们。
上例中,其实就保存了一个类名,因为所有的其他东西都是类定义的东西,是不变的,所以只序列化一个AAA类名。反序列化的时候找到类就可以恢复一个对象。
import pickle
# 对象序列化
class AAA:
def __init__(self):
self.aaaa = 'abc'
a1 = AAA() # 创建AAA类的对象
# 序列化
ser = pickle.dumps(a1)
print('ser={}'.format(ser)) # AAA aaaa abc
# 反序列化
a2 = pickle.loads(ser)
print(a2, type(a2))
print(a2.aaaa)
print(id(a1), id(a2))
序列化应用
一般来说,本地序列化的情况,应用较少。大多数场景都应用在网络传输中。
将数据序列化后通过网络传输到远程节点,远程服务器上的服务将接收到的数据反序列化后,就可以使用了。但是,要注意一点,远程接收端,反序列化时必须有对应的数据类型,否则就会报错。尤其是自定义类,必须远程得有一致的定义。
现在,大多数项目,都不是单机的,也不是单服务的,需要多个程序之间配合。需要通过网络将数据传送到其他节点上去,这就需要大量的序列化、反序列化过程。
但是,问题是,Python程序之间还可以都是用pickle解决序列化、反序列化,如果是跨平台、跨语言、跨协议pickle就不太适合了,就需要公共的协议。例如XML、Json、Protocol Buffer等。
不同的协议,效率不同、学习曲线不同,适用不同场景,要根据不同的情况分析选型。
Json
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c组织制定的JS规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
http://json.org/
Json的数据类型
Python 与 Json
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
d = {'name':'Tom', 'age':20, 'interest':('music', 'movie'), 'class':['python']}
# 序列化
j = json.dumps(d)
print(j, type(j)) # 请注意引号、括号的变化,注意数据类型的变化
#反序列化
d1 = json.loads(j)
print(d1)+
print(id(d), id(d1)) # 地址不一致
一般json编码的数据很少落地,数据都是通过网络传输。传输的时候,要考虑压缩它。
本质上来说它就是个文本,就是个字符串。
json很简单,几乎编程语言都支持Json,所以应用范围十分广泛。
json 不能序列化所有数据类型,只能序列化指定的数据类型,得到一个字符串,反序列得到原有的序列类型。
MessagePack
MessagePack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。
它可以像JSON那样,在许多种语言之间交换结构对象。
但是它比JSON更快速也更轻巧。
支持Python、Ruby、Java、C/C++等众多语言。宣称比Google Protocol Buffers还要快4倍。
兼容 json和pickle。
常用方法
packb 序列化对象。提供了dumps来兼容pickle和json。
unpackb 反序列化对象。提供了loads来兼容。
pack 序列化对象保存到文件对象。提供了dump来兼容。
unpack 反序列化对象保存到文件对象。提供了load来兼容。
import pickle
import msgpack
import json
d = {'person': [{'name': 'tom', 'age': 18}, {'name': 'jerry', 'age': 16}], 'total': 2}
# json
data = json.dumps(d) # JSON 类型
print(type(data), len(data), data)
print(data.replace(' ', ''))
print(len(data.replace(' ', ''))) # 72 bytes 注意这样替换的压缩是不对的
# pickle
data = pickle.dumps(d)
print(type(data), len(data), data) # 101 bytes
# msgpack
data = msgpack.dumps(d)
print(type(data), len(data), data) # 48 bytes # 使用mapack 明显压缩了长度
print('-' * 30)
u = msgpack.unpackb(data) # 反序列化
print(type(u), u)
print(msgpack.loads(data))
u = msgpack.loads(data, encoding='utf-8') # 反序列化
print(type(u), u)
上一篇: 有关PHP的DEBUG一点想法
推荐阅读
-
Python开发之序列化与反序列化:pickle、json模块使用详解
-
Python 序列化模块(json,pickle,shelve) 百日筑基之得气(三)
-
Python 对象序列化与反序列化之pickle json详细解析
-
Python 入门之 内置模块 -- 序列化模块(json模块、pickle模块)
-
Python3.5 Json与pickle实现数据序列化与反序列化操作示例
-
Python之数据序列化(json、pickle、shelve)详解
-
Python开发之序列化与反序列化:pickle、json模块使用详解
-
python 序列化之JSON和pickle详解
-
Python之数据序列化(json、pickle、shelve)详解
-
python 序列化之JSON和pickle详解