把数据序列化可以更加方便的在程序之间传输
在python中,常用json和pickle两个模块来对数据序列化:
json模块:
json,用于字符串 和 python数据类型间进行转换
Json 模块提供了四个功能:dumps、dump、loads、load
json.dump() 将数据通过特殊的形式转换为所有程序语言都认识的字符串,并写入文件
json.dumps() 将数据通过特殊的形式转换为所有程序语言都认识的字符串
json.dump和json.dumps很不同,json.dump主要用来json文件读写,和json.load函数配合使用。
json.loads() 加载json文件的内容,并转换为python数据类型
1 ''' json.dumps 和 json.loads 应用''' 2 >>> import json 3 >>> user_info= { 4 'name':'root', 5 'age':22, 6 'job':'python' 7 } 8 >>> with open('data_json.txt','w') as f: 9 f.write(json.dumps(user_info)) #先序列化,再写入文件 10 12 44 # 这是序列化后单个字符的数量(字典在打印时,每个键值对的值前面会有个空格) 13 >>> len(user_info) 14 3 15 >>> with open('data_json.txt','r') as fr: 16 json.loads(fr.read()) #先从文件读出来,再反序列化 17 19 {'name': 'root', 'age': 22, 'job': 'python'} 20 >>>
1 >>> '''json.dump 和 json.load使用''' 2 >>> import json 3 >>> user_info = {'name': 'root', 'age': 22, 'job': 'python'} 4 >>> 5 >>> with open('data_json1.txt','w') as fw: 6 json.dump(user_info,fw) 7 #json.dump(要被序列化对象,文件句柄) 8 9 >>> with open('data_json1.txt','r') as fr: 10 json.load(fr) 11 #json.load(文件句柄) 12 13 {'name': 'root', 'age': 22, 'job': 'python'} 14 >>>
pickle模块:
pickle,用于python特有的类型 和 python的数据类型间进行转换
pickle模块提供了四个功能:dumps、dump、loads、load
pickle.dumps() 将数据通过特殊的形式转换成只有python语言认识的字符串,不需要写入文件
pickle.dump() 将数据通过特殊的形式转换成只有python语言认识的字符串,并写入文件
pickle.dump(obj, fw, [,protocol])
注解:将对象obj保存到文件fw ('w'方式打开的文件句柄)中去。
pickle.dumps(obj):以字节对象形式返回封装的对象,不需要写入文件中
pickle.load(fr)
注解:从file中读取一个字符串,并将它重构为原来的python对象。
fr : 'r'方式打开的文件句柄,有read()和readline()接口。
pickle.loads(bytes_object): 从字节对象中读取被封装的对象,并返回
1 >>> ''' pickle.dumps 和 pickle.loads 使用''' 2 >>> import pickle 3 >>> user_info = {'name': 'root', 'age': 22, 'job': 'python'} 4 >>> 5 >>> with open('data_pickle.txt','wb') as fw: #用pickle对数据序列化时,要用二进制打开进行读、写 6 fw.write(pickle.dumps(user_info)) 7 9 65 10 >>> with open('data_pickle.txt','rb') as fr: 11 pickle.loads(fr.read()) 12 13 14 {'name': 'root', 'age': 22, 'job': 'python'} 15 >>>
1 >>> '''pickle.dump 和 pickle.load使用''' 2 >>> import pickle 3 >>> user_info = {'name': 'root', 'age': 22, 'job': 'python'} 4 >>> 5 >>> with open('data_pickle1.txt','wb') as fw: 6 pickle.dump(user_info,fw) 7 8 >>> with open('data_pickle1.txt','rb') as fr: 9 pickle.load(fr) 10 11 {'name': 'root', 'age': 22, 'job': 'python'} 12 >>>
json和pickle两个模块的方法一样,只是在用pickle序列化时,打开文件的方式必须是二进制('wb','rb')
以上利用json或pickle都是序列化一条数据,若要同时序列化多条数据,则pickle和json都很麻烦了(两种方式操作过程一样)
>>> '''用 pickle 序列化多条数据''' >>> import pickle >>> >>> user_info = {'name': 'root', 'age': 22, 'job': 'python'} >>> user_list = ['root','admin','xsec'] >>> job_list = ['python','php','js'] >>> >>> with open('more_data_pickle.txt','wb') as fw: fw.write(pickle.dumps(user_info)) fw.write(pickle.dumps(user_list)) fw.write(pickle.dumps(job_list)) 65 42 40 >>> with open('more_data_pickle.txt','rb') as fr: pickle.loads(fr.read()) pickle.loads(fr.read()) pickle.loads(fr.read()) #用dumps可以序列化多条数据,但是用loads反序列化时,报错了 {'name': 'root', 'age': 22, 'job': 'python'} Traceback (most recent call last): File "<pyshell#83>", line 3, in <module> pickle.loads(fr.read()) EOFError: Ran out of input >>> fr = open('more_data_pickle.txt','rb') >>> pickle.loads(fr.read()) {'name': 'root', 'age': 22, 'job': 'python'} >>> pickle.loads(fr.read()) Traceback (most recent call last): File "<pyshell#86>", line 1, in <module> pickle.loads(fr.read()) EOFError: Ran out of input >>> with open('more_data_pickle.txt','wb') as fw: #用dump和load成功序列化和反序列化多条数据 pickle.dump(user_info,fw) pickle.dump(user_list,fw) pickle.dump(job_list,fw) >>> with open('more_data_pickle.txt','rb') as fr: pickle.load(fr) pickle.load(fr) pickle.load(fr) #在生产时这样load不知道到底要load多少次才能取到想要的数据 {'name': 'root', 'age': 22, 'job': 'python'} #按照dump的先后顺序,依次load (入单向队列,先进先出) ['root', 'admin', 'xsec'] ['python', 'php', 'js'] >>>
由上面可知,在序列化时问题还不大,可是当我们在读取数据时,感觉就是毫无条理,不知道合适才能取到我们想要的数据。由此,我们有必要学习下面这个模块
shelve 模块
shelve模块是一个简单的通过key,value形式将内存数据通过文件持久化的模块,可以持久化任何pickle可以支持的python数据格式
( shelve 的实质:对pickle再一次封装)
shelve较于pickle优点:
在dump多条数据时,pickle需要dump多次,其在取时,也要对应load多次(先进先出)
而shelve在持久化多条数据之后,只需要根据不同的key就可以调用不同的数据
1 >>> 2 >>> import shelve 3 >>> user_info = {'name': 'root', 'age': 22, 'job': 'python'} 4 >>> user_list = ['root', 'admin', 'xsec'] 5 >>> job_list = ['python', 'php', 'js'] 6 >>> #用shelve序列化数据 7 >>> so = shelve.open('more_data_shelve.txt') #打开一个用来存储序列化后的数据的文件(不需要打开方式) 8 >>> so['u_i'] = user_info 9 >>> so['u_l'] = user_list #其中的键名('u_i'...)是自定义的,存数据不要求顺序,后面取数据也不要求顺序 10 >>> so['j_l'] = job_list 11 >>> so.close() #存完了记得关闭文件 12 >>>
#反序列化数据 13 >>> so1 = shelve.open('more_data_shelve.txt') #打开之前存储序列化后的数据的文件,同样不要打开方式 14 >>> so1['u_l'] 15 ['root', 'admin', 'xsec'] 16 >>> so1['j_l'] #可以通过键名,只取想要的数据,不需要全部反序列化 17 ['python', 'php', 'js'] 18 >>> so1['u_i'] 19 {'name': 'root', 'age': 22, 'job': 'python'} 20 >>> so1.close() #关闭文件 21 >>>