序列化模块
json
# 我们今天学习下序列化,什么是序列化呢? 将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。 # 为什么要有序列化模块: 比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给? # 现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。 但是我们都知道,对于文件来说是没有字典这个概念的, # 所以我们只能将数据转换成字典放到文件中。 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? # 没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串, 但是你要怎么把一个字符串转换成字典呢? # 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。 # eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。 # BUT!强大的函数有代价。安全性是其最大的缺点。 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句, # 那么后果实在不堪设设想。 # 而使用eval就要担这个风险。 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构) # 序列化的目的 # socketserver模块-循环接收0、以某种存储形式使自定义对象持久化; # 2、将对象从一个地方传递到另一个地方。 # 3、使程序更具维护性。 ###json模块 #socketserver模块-循环接收0、用于多种语言交互——编程语言的通用数据 #2、内置的,不需要安装的,直接导入使用 ##dumps、loads、dump、load方法 ###dump与load有“持久化”功能! import json ########################################### # dumps方法——将字典(主要)对象转换成字符串 dic = {'a1':1,'b':2} s1 = json.dumps(dic) print(s1,type(s1)) #{"a1": socketserver模块-循环接收0, "b": 2} <class 'str'> # loads方法——将字符串转换成字典 d1 = json.loads(s1) print(d1,type(d1))#{'a1': socketserver模块-循环接收0, 'b': 2} <class 'dict'> di = '{"a1":socketserver模块-循环接收0}' dl = '[socketserver模块-循环接收0,2,3,4,5]' dii = json.loads(di) dll = json.loads(dl) print(dii,type(dii))#{'a1': socketserver模块-循环接收0} <class 'dict'> print(dll,type(dll))#[socketserver模块-循环接收0, 2, 3, 4, 5] <class 'list'> ########################################### # load与dump dic1 = {'a1':1,'b':2} json.dump(dic1,open('a1','w',encoding='utf8')) d = json.load(open('a1','r',encoding='utf8')) d['a1'] = 11 print(d)#{'a1': zz, 'b': 2} ###注意,手动在文件里写的话,文件里的键值如果是字符串的话必须用双引号!!! ############################################# ###总结### # json.load()#参数:是文件句柄(w模式),将文件中字符串转换为字典 # json.dump()#参数:第一个是对象(字典),第二个是文件句柄(r模式),将字典转换为字符串写入到文件中 # json.dumps() #参数:obj(字典),将字典转换为字符串 # json.loads() #参数:字符串(类字典),将字符串转换为字典 ###dumps与loads### dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串 print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"} #注意,json转换完的字符串类型的字典中的字符串是由""表示的 dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典 #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示 print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} list_dic = [1,['a1','b','c'],3,{'k1':'v1','k2':'v2'}] str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型 print(type(str_dic),str_dic) #<class 'str'> [socketserver模块-循环接收0, ["a1", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] list_dic2 = json.loads(str_dic) print(type(list_dic2),list_dic2) #<class 'list'> [socketserver模块-循环接收0, ['a1', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}] ###dump与load### f = open('json_file','w') dic = {'k1':'v1','k2':'v2','k3':'v3'} json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close() f = open('json_file') dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 f.close() print(type(dic2),dic2)
pickle
###pickle——pickle只支持Python语言!!! # 用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 # pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表... # 可以把python中任意的数据类型序列化)pickle是python特有的模块. ### dumps、loads、dump、load ### dump、load支持持久化 import pickle #将对象转换为类似二进制 print(pickle.dumps({'a1':1}))#b'\x80\x03}q\x00X\x01\x00\x00\x00aq\x01K\x01s.' #将一堆类似于二进制的东西转换为字典 print(pickle.loads(b'\x80\x03}q\x00X\x01\x00\x00\x00aq\x01K\x01s.'))#{'a1': socketserver模块-循环接收0} #注意是wb形式,不能指定编码! pickle.dump({'b':2},open('p','wb')) d = pickle.load(open('p','rb')) print(d) #{'b': 2} ################################## ###pickle与json的对比### # loads—— json里是:将字符串转为字典;pickle里:将字节转换为字典 # dumps——json里是:将字典转换为字符串;pickle里是:将字典转换为字节 # load——json里是:将文件中的字符串转换为字典;pickle里是:将文件中的字节转换为字典 # dump——json里是:将字典转换为字符串写入到文件中;pickle里是:将字典转换为字节写入到文件中 ##################################
shelve
###文件+字典操作 import shelve #没有encoding f = shelve.open('sh',writeback=True) #创建一个文件 f['name'] = 'wanghw' f['age'] = 18 print(f['name']) print(f['age']) f['name'] = ['wanghw','whw'] print(f['name']) ###查看这个字典! for i in f: print(i) #获取到所有的键,必须用for print(f[i])# 获取所有的值 l = f.items() print(list(l))#[('name', ['wanghw', 'whw']), ('age', 18)] ######## # shelve模块自动帮我们 dump与load了! # 注意,“键”只能是字符串的形式!!! # 注意,以后会出现一个问题:对字典的操作内容,有时候写不进去, # 解决:在open的时候加一个参数:writeback=True # f = shelve.open('sh',writeback=True) ################################################## ###总结:### # json最常用!前后端分离的时候数据交互!——json必须会 # pickle——只有python有,不怎么常用 ——pickle必须了解 # shelve——纯python建议使用shelve,简单 ——shelve必须了解
练习
import json s = json.dumps({'a':1,'aa':11}) print(s) d = json.loads(s) print(d) # f = open('a11','w',encoding='utf8') # json.dump({'aa':zz},f) # f.close() with open('a11','w',encoding='utf8')as f: json.dump({'a12':12},f) with open('a11','r',encoding='utf8')as f: d = json.load(f) print(d)
import pickle def func1(): print(1) def func2(): print(2) if __name__ == '__main__': f1 = func1 f2 = func2 with open('p1','ab')as f: pickle.dump(f1,f) pickle.dump(f2,f) with open('p1','rb')as f: func1 = pickle.load(f) func2 = pickle.load(f) fff = pickle.load(f) fff2 = pickle.load(f) print(func1) print(func2) print(fff) print(fff2) func1() func2() fff() fff2() # for em in f: # print(em) # func = pickle.load(em) # func()
import json dic = {'name':'wanghw','age':21,'sex':'male'} with open('whw','w',encoding='utf8')as f: json.dump(dic,f) with open('whw','r',encoding='utf8')as f: dic = json.load(f) print(dic) #{'name': 'wanghw', 'age': 21, 'sex': 'male'} dic = {'name':'whw','age':22} s = json.dumps(dic) print(s,type(s))#{"name": "whw", "age": 22} <class 'str'> d = json.loads(s) print(d,type(d))#{'name': 'whw', 'age': 22} <class 'dict'>