一:序列化模块
1,什么叫序列化?
序列化就是将原本的字典、列表等内容转换成一个字符串。python中的序列化模块有 json,pickle,shelve。
ps:能存储在文件中的一定是字符串或者是字节,能在网络上传输的只有字节。
2,为什么要进行序列化?
因为在网络上和文件中能存在的只有字节
3,json模块
所有的编程语言都通用的序列化格式,但它支持的数据类型非常有限(数字 字符串 列表 字典)
Json模块提供了四个功能:dumps、dump、loads、load
(1) dumps和loads
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json dic = {"张三":(190,90)} # 序列化 ret = json.dumps(dic,ensure_ascii=False) #将字典转化为str print(type(dic),dic) print(type(ret),ret) # 反序列化 res = json.loads(ret) #将str转化为字典 print(type(res),res)
(2) dump和load 是直接将对象序列化之后写入文件,依赖一个文件句柄
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json dic = {"大表哥":(190,90)} f = open('大表哥','w',encoding='utf-8') json.dump(dic,f,ensure_ascii=False) # 先接收要序列化的对象 再接受文件句柄 f.close() f = open('大表哥','r',encoding='utf-8') ret = json.load(f) print(type(ret),ret)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json data = {'username':['李华','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators(',',':'),ensure_ascii=False) print(json_dic2)
ps:dumps序列化 loads反序列化 只在内存中操作数据 主要用于网络传输 和多个数据与文件打交道
dump序列化 load反序列化 主要用于一个数据直接存在文件里—— 直接和文件打交道
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json dic1 = {"大表哥":(190,90)} dic2 = {"2表哥":(190,90)} dic3 = {"3表哥":(190,90)} f = open('大表哥','a',encoding='utf-8') str1 = json.dumps(dic1) f.write(str1+' ') str2 = json.dumps(dic2) f.write(str2+' ') str3 = json.dumps(dic3) f.write(str3+' ') f.close() f = open('大表哥','r',encoding='utf-8') for line in f: print(json.loads(line.strip())) f.close()
4,pickle模块
只能在python语言的程序之间传递数据,它支持python中所有的数据类型
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import pickle dic = {(190,90):"大表哥"} ret = pickle.dumps(dic) # 序列化结果 不是一个可读的字符串 而是一个bytes类型 print(ret) print(pickle.loads(ret))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import pickle dic = {(190,90):"大表哥"} f = open('大表哥2','wb') # 使用pickle dump必须以+b的形式打开文件 pickle.dump(dic,f) f.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#关于写多行 import pickle dic1 = {"大表哥":(190,90)} dic2 = {"2表哥":(190,90)} dic3 = {"3表哥":(190,90)} f = open('大表哥3','wb') pickle.dump(dic1,f) pickle.dump(dic2,f) pickle.dump(dic3,f) f.close() # 读写入的多行 f = open('大表哥3','rb') while True: try: print(pickle.load(f)) except EOFError: break
ps:json 在写入多次dump的时候 不能对应执行多次load来取出数据,pickle可以。json 如果要写入多个元素 可以先将元素dumps序列化,f.write(序列化+' ')写入文件。读出元素的时候,应该先按行读文件,在使用loads将读出来的字符串转换成对应的数据类型。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A: def __init__(self,name,age): self.name=name self.age=age a = A('张三',18) import pickle f = open('大侄子1','wb') pickle.dump(a,f) f.close() f = open('大侄子1','rb') obj = pickle.load(f) print(obj.__dict__)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class A: def __init__(self,name,age): self.name=name self.age=age a = A('张三',18) import pickle ret = pickle.dumps(a) print(ret) obj = pickle.loads(ret) print(obj.__dict__)
5,shelve模块
python 专有的序列化模块 只针对文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import shelve # python 专有的序列化模块 只针对文件 f = shelve.open('shelve_file') # 打开文件 f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据 f.close() f = shelve.open('shelve_file', flag='r') f['key']['int'] = 50 # 不能修改已有结构中的值 f['key']['new'] = 'new' # 不能在已有的结构中添加新的项 f['key'] = 'new' # 但是可以覆盖原来的结构 existing = f['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错 f.close() print(existing) f.close()
6,hashlib模块
(1) hashlib是一种摘要算法,它能将字符串转化为数字,对于不同的算法,转化的数字一定不相同,无论在哪台机器上,在什么时候计算,对相同的字符串结果总是一样的。而且该摘要过程不可逆。
(2) hashlib算法应用于文件的一致性校验,密文验证的时候的加密
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import hashlib m = hashlib.md5() m.update('dazhizi'.encode('utf-8')) print(m.hexdigest())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import hashlib m = hashlib.md5('wahaha'.encode('utf-8')) m.update('123456'.encode('utf-8')) print(m.hexdigest())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
username = 'alex' m = hashlib.md5(username[:2:2].encode('utf-8')) m.update('123456'.encode('utf-8')) print(m.hexdigest())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
md5obj = hashlib.md5() md5obj.update(b'hello,') md5obj.update(b'alex,') md5obj.update(b'I know your ') md5obj.update(b'password is alex3714') print(md5obj.hexdigest()) # 一段字符串直接进行摘要和分成几段摘要的结果是相同的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import hashlib def check(filename): md5obj = hashlib.md5() with open(filename,'rb') as f: content = f.read() md5obj.update(content) return md5obj.hexdigest() #适合两个文件较大时的一致性校验 def check(filename): md5obj = hashlib.md5() with open(filename,'rb') as f: while True: content = f.read(4096) if content: md5obj.update(content) else: break return md5obj.hexdigest() ret1 = check('file1') ret2 = check('file2') print(ret1) print(ret2)
7,几种序列化模块的比较
序列化就是把数据类型转化为字符串。
(1)json,在所有语言中通用 ,只对有限的数据类型进行序列化 字典 列表 字符串 数字 元组。在多次写入dump数据进入文件的时候,不能通过load来取。
(2)pickle,只能在python中使用 对绝大多数数据类型都可以进行序列化,在load的时候,必须拥有被load数据类型对应的类在内存里。
# dumps 序列化
# loads 反序列化
# dump 直接向文件中序列化
# load 直接对文件反序列化