python常见模块之序列化(json与pickle以及shelve)

什么是序列化?

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

为什么要序列化?

1:持久保存状态

需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状态'会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。

内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。

在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。

具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。

2:跨平台数据交互

序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

怎么序列化

之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,

json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

json

json支持的数据格式有限,有int str list dict以及特殊的tuple(会将tuple转为list)

Json模块提供了四个功能:dumps、dump、loads、load

dumps和loads主要是在内存内操作,如下:

1 import json
2 
3 list = ['a','b','c']
4 
5 list_str = json.dumps(list)
6 print(list_str)     #["a", "b", "c"]
7 
8 list2 = json.loads(list_str)
9 print(list2)        #['a', 'b', 'c']

 

而dump和load是从文件内操作,如下:

1 import json
2 
3 list = ['a','b','c']
4 
5 with open('test','w',encoding='utf-8') as f:
6     json.dump(list,f)
7 
8 with open('test','r',encoding='utf-8') as f2:
9     json.load(f2)

pickle

用法与json类似,不过pickle不能跨语言,优点是它支持python所有的数据类型

需要注意的是,pickle是以bytes类型来进行序列化的

1 import pickle
2 
3 list = ['a','b','c']
4 list_str = pickle.dumps(list)
5 print(list_str)         #b'\x80\x03]q\x00(X\x01\x00\x00\x00aq\x01X\x01\x00\x00\x00bq\x02X\x01\x00\x00\x00cq\x03e.'
6 
7 list2 = pickle.loads(list_str)
8 print(list2)            #['a', 'b', 'c']

而正因为pickle是以bytes类型进行序列化的,所以在用dump和load方法对文件进行写入或者反序列化的时候,要以wb或者rb模式打开,如下:

1 import pickle
2 
3 list = ['a','b','c']
4 with open('test','wb') as f:
5     pickle.dump(list,f)
6 
7 with open('test','rb') as f2:
8     pickle.load(f2)

 

shelve

shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。

 1 import shelve
 2 f = shelve.open('test1')
 3 f['key'] = {'a':1, 'b':2, 'c':'sss'}  #直接对文件句柄操作,就可以存入数据
 4 f['key2'] = {'d':3, 'e':4, 'f':'ddd'}
 5 f.close()
 6 
 7 f1 = shelve.open('test1')
 8 dic1 = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
 9 dic2 = f1['key2']
10 f1.close()
11 print(dic1)
12 print(dic2)

 

posted @ 2018-01-11 15:13  人生不如戏  阅读(335)  评论(0编辑  收藏  举报