1.Json模块
a:什么是json模块:
json模块用于字符串和Python数据类型间进行转换
b:json的四个功能:
1)dumps:将列表,字典,元组,数字-->字符串
dumps直接操作变量,操作完成变成了一个字符串变量;
import json dic = {'a':2,'b':4,'d':[5,6,8,7]} str_dict = json.dumps(dic) print(str_dict,type(str_dict)) #输出结果: {"a": 2, "b": 4, "d": [5, 6, 8, 7]} <class 'str'> @结果为字符串类型,但是这个新变量中的字符串为双引号,且只能为双引号;
dumps中的参数:
data = {'username':['李华','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False) print(json_dic2) #当你的字典特别长或则特别大的时候就会写不下,所以这时会用到它的参数调整你输出的格式 #sort_keys:对字典的key值进行了排序, #ident表示每一行的缩进 #separate表示分隔符, 这种格式一般不在存文件时应用该方法,只是让程序员看起来方便,因为相对浪费空间;
2)loads
loads就是将字符串变量转为相应格式的数据类型;
import json dic = {'a':2,'b':4,'d':[5,6,8,7]} str_dict = json.dumps(dic) print(str_dict,type(str_dict)) #将字典转为字符串 new_dic = json.loads(str_dict) print(new_dic,type(new_dic)) #将字符串转为字典 #输出结果 {"a": 2, "b": 4, "d": [5, 6, 8, 7]} <class 'str'> {'a': 2, 'b': 4, 'd': [5, 6, 8, 7]} <class 'dict'>
3)dump
dump应用于你只想往文件写入,将数据类型相互转换
import json dic = {'a':2,'b':4,'d':[5,6,8,7]} with open('aaa',mode='a+',encoding='utf-8')as f: json.dump(dic,f) #文件 aaa {"a": 2, "b": 4, "d": [5, 6, 8, 7]} #相当于默认帮你执行了f.write()方法
dic = {'a':2,'b':4,'d':'中国'} #当dump方法遇见中文的时候 json.dump(dic,f) #{"a": 2, "b": 4, "d": "u4e2du56fd"} #修改参数ensure_asill=False就会切换为utf-8 json.dump(dic,f,ensure_ascii=False) #{"a": 2, "b": 4, "d": "中国"}
4)load
load将文件中的字符串转为相应的数据类型,而且一行不能有多个数据类型
with open('aaa',encoding='utf-8')as f: print(json.load(f)) #输出结果: {'a': 2, 'b': 4, 'd': '中国'}
5)json的优缺点:
优点:可以跨平台语言,支持所有语言;
缺点:
1)对字典的key值的限制,再转为字符串时,key值只能为字符串,如果是数字,会强转为字符串,然后你再转回时,也就变为字符串了;
import json dic = {1:2,'b':4,'d':5} print(json.dumps(dic)) print(json.loads(json.dumps(dic))) #输出结果 {"1": 2, "b": 4, "d": 5} {'1': 2, 'b': 4, 'd': 5}
2)对于字典的value值如果为元组,会请转为列表;
import json dic = {1:2,'b':4,'d':(1,2,3)} print(json.dumps(dic)) print(json.loads(json.dumps(dic))) #输出结果 {"1": 2, "b": 4, "d": [1, 2, 3]} {'1': 2, 'b': 4, 'd': [1, 2, 3]} #key值不支持是元组TypeError: keys must be a string
3)json中的要操作的文件如果有引号,必须为双引;
4)当有中文格式时,要将dumps的ensure_ascii设置为False,才能进行转换;
5)如果想要多行写入,然后读取,要利用dumps和loads一起使用:
import json dic = {2:2,'b':4,'d':(1,2,3)} lst = [1,2,'a',(1,2,3)] with open('aaa','w')as f: f.write(json.dumps(dic)+' ') f.write(json.dumps(lst)+' ') with open('aaa')as f1: for line in f1: print(json.loads(line))
2.pickle模块
a:和json模块一样,同样也是将数据类型转为字符串
b:pickle可以将任何数据类型转为字符串;
c:pickele是以bytes格式显示的;
d:pickle的dumps和loads,dump和load跟json一样
e:不同点是pickle可以对对象操作,转为字符串
import pickle class A: def __init__(self,name,age): self.name = name self.age = age def read(self): print(222) a = A('name',10) with open('aaa',mode = 'wb')as f: pickle.dump(a,f) with open('aaa','rb')as f1: ret = pickle.load(f1) print(ret.__dict__) ret.read() #可用于对游戏的存档和读档
#pickle的应用,将对象一一提取出来,用一个异常处理
import pickle class A: def __init__(self,name,age): self.name = name self.age = age def read(self): print(222) a = A('name1',10) b = A('name2',15) c = A('name3',18) with open('aaa',mode = 'wb')as f: pickle.dump(a,f) pickle.dump(b,f) pickle.dump(c,f) with open('aaa','rb')as f1: while True: choose = True try: obj = pickle.load(f1) if 'name5' == obj.name: print(obj.__dict__) break except EOFError: choose = False break if choose == False: #如果没有此对象,给一个提示 print('None') #输出结果: None
这样就可以将对象的属性一一保存起来,等到用到的时候再提取出来;
3.shelve模块
a:shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。
import shelve f = shelve.open('shelve_file') f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据 f.close() import shelve f1 = shelve.open('shelve_file') existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错 f1.close() print(existing)
这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB
由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。
总结:序列化的好处:
1.以某种储存形式使自定义对象持久化;
2.将对象从一个地方传递到另一个地方;
3.使程序更具有维护性