python序列化模块
Posted 宁静~朝夕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python序列化模块相关的知识,希望对你有一定的参考价值。
1. 序列化一般用于二个地方:
1> 数据存储,如写文件,数据入库
2> 网络上传输数据的时候
2. 序列化/反序列化:
1> 序列化:从数据类型(int,dict,tuple,list等) --> 字符串的过程
2> 反序列化:从字符串 --> 数据类型的过程
3. json (常用模块):
1> 通用的序列化格式
2> 只有很少的一部分数据类型能通过json转化为字符串
3> json能序列化的数据类型有:数字,字符串,列表,字典,元组(序列化时当成列表序列化的)
#json dumps序列化方法 loads反序列化方法 import json dic={"k":"v"} print(type(dic),dic) str_d=json.dumps(dic) #序列化 print(type(str_d),str_d) #json格式: \'{"k1":"v1"}\' , 外面是一个单引号,内部的所有字符串都要使用双引号引起来 dic_d=json.loads(str_d) #反序列化 print(type(dic_d),dic_d)
4> dump:将数据序列化到文件中(只有字符串才能写入文件)
import json # dump:与文件相关的操作 dic = {\'a\':\'中国\',\'b\':\'22\'} f=open(\'ff\',\'w\',encoding=\'utf-8\') json.dump(dic,f,ensure_ascii=False) #序列化, ensure_ascii为False时,中文字符写入文件中后仍为中文
f.close()
5> load: 将文件中的字符中反序列化成原数据类型的数据
import json f=open(\'ff\',\'r\',encoding=\'utf-8\') #ff是一个已存的文件,写了一个字典的数据
dic_d =json.load(f) #反序列化
f.close()
print(type(dic_d),dic_d)
重点:
a> dumps/loads: 直接操作内存中的数据类型;
b> dump/load:直接操作文件中的数据;
c> dump/load:dump可以将多次写入内容到文件中,但是写入后,load无法多次读出,因为不知道每次读到哪里;
d> 所以dump和load使用时,一次性写入全部内容,再一次性读出所有内容;
6> 如果想多次写入内容后,再多次读出来,怎么办?
import json #一个一个字典的写入 list_1 = [{\'a\':\'中国\'},{\'b\':\'22\'},{\'c\':\'33\'}] f=open(\'ff\',\'w\',encoding=\'utf-8\') for dic in list_1: str_dic=json.dumps(dic,ensure_ascii=False) f.write(str_dic+\'\\n\') f.close() #一行一行读出 f=open(\'ff\',encoding=\'utf-8\') list_2=[] for line in f: dic=json.loads(line.strip()) #strip()去掉换行 list_2.append(dic) f.close() print(list_2)
4. pickle:
1> 所有的python中的数据类型都可以通过pickle转化成字符串;
2> pickle序列化的内容只有python能识别;
3> 部分反序列化依赖python代码;
4> 同json一样,常用方法有 dumps/loads,dump/load;
5> dumps出来的内容为base格式(二进制)字符串;
6> dump和load时,对于文件的写入和读出,要用\'wb\'和‘rb’形式;
7> dump和load,可以多次dump内容写入文件,再多次load从文件中读出;
import pickle,time struct_time1=time.localtime(1000000000) struct_time2=time.localtime(2000000000) print(struct_time1) print(struct_time2) f=open(\'pickle_file\',\'wb\') pickle.dump(struct_time1,f) #可以多次dump写入 pickle.dump(struct_time2,f) f.close() f=open(\'pickle_file\',\'rb\') struct_time1=pickle.load(f) #再多次load读出 struct_time2=pickle.load(f) print(struct_time1.tm_year) print(struct_time2.tm_year)
5. shelve:
1> 操作简单,序列化句柄;
2> 使用句柄直接操作,非常方便;
3> 只有一个open方法,通过key来访问,用法类似字典;
import shelve f=shelve.open(\'shelve_file\') f[\'firt\']={\'int\':10,\'float\':9.5,\'string\':\'Sample data\'} #直接对文件句柄f操作,就可以存入数据 f[\'second\']={1,2.4,\'aa\',(\'中国\',\'bb\')} #写入后,会生成一些后缀为.bak,.dat,.dir文件 f.close() f1=shelve.open(\'shelve_file\') existing1=f1[\'firt\'] #取出数据时也只需要直接用key获取即可,但是若key不存在会报错 existing2=f1[\'second\'] f1.close() print(existing1) print(existing2)
4> shelve在默认情况下不会记录持久化对象的任务修改,需要在shelve.open()时修改默认参数writeback,否则对象的修改不会保存
import shelve f1=shelve.open(\'shelve_file\') print(f1[\'firt\']) f1[\'firt\'][\'new_value\']=\'this was a new add value\' print(f1[\'firt\']) #新增加的内容没有保存下来 f1.close()
import shelve f1=shelve.open(\'shelve_file\',writeback=True) print(f1[\'firt\']) f1[\'firt\'][\'new_value\']=\'this was a new add value\' print(f1[\'firt\']) #新增加的内容保存下来了!! f1.close()
5> writeback优化点:
a> 优化:让对象的持久化对用户更加的透明了;
b> 缺点:shelve在open()时增加额外内存,当DB在close()时,会将缓存中每个对象都重新写入DB,因为shelve无法知道缓存中哪些对象修改了,哪些对象没有修改;
以上是关于python序列化模块的主要内容,如果未能解决你的问题,请参考以下文章
Python练习册 第 0013 题: 用 Python 写一个爬图片的程序,爬 这个链接里的日本妹子图片 :-),(http://tieba.baidu.com/p/2166231880)(代码片段