在介绍pickle模块之前,我们先了解一下python中的模块以及模块的分类,可以让我们对模块有更深入的了解。
(1) 模块是什么:
(2) 模块的分类:
在Python中,模块分为以下几种:
(1)pickle模块:
pickle模块是python语言的一个系统内置模块,安装python后已包含pickle库,不需要单独再安装。
(2)pickle模块的特点:
1、只能在python中使用,只支持python的基本数据类型,是python独有的模块。
2、序列化的时候,只是序列化了整个序列对象,而不是内存地址。
3、pickle有两类主要的接口,即序列化和反序列化;
通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;
通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
(3)为什么需要序列化和反序列化操作呢?
1、便于存储
序列化过程是将Python程序运行中得到了一些字符串、列表、字典等数据信息转变为二进制数据流。这样信息就容易存储在硬盘之中,当需要读取文件的时候,从硬盘中读取数据,然后再将其反序列化便可以得到原始的数据。
2、便于传输
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把对象转换为字节序列,在网络上传输;接收方则需要把字节序列在恢复为对象,得到原始的数据。
(1)序列化操作:
序列化方法1:pickle.dump()
格式为:pickle.dump(obj,file)
该方法是将序列化后的对象obj以二进制形式写入文件file中,进行保存,不能直接预览。 关于文件file,必须是以二进制的形式进行操作(写入)。
示例如下:将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中
import random import pickle #初始化成绩表为空 cjb=[] #写入5个学生的数据到成绩表中 for i in range(5): name=input("name:") #姓名 cj=random.randint(50,100) #随机生成50——100之间的整数作为成绩 cjb.append([name,cj]) print(cjb) #将成绩表中的数据保存到cjb.txt文件中 with open('cjb.txt','wb')as f: pickle.dump(cjb,f) print("结果已保存") 结果如下: name:1 name:2 name:3 name:4 name:5 [['1', 65], ['2', 82], ['3', 95], ['4', 99], ['5', 59]] 结果已保存
序列化方法2:pickle.dumps()
格式为:pickle.dumps(obj)
pickle.dumps()方法跟pickle.dump()方法不同:pickle.dumps()方法不需要写入文件中,而是直接返回一个序列化的bytes对象。
示例如下:与上面的例子一样,只是方法不同,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中
import random import pickle #初始化成绩表为空 cjb=[] #写入5个学生的数据到成绩表中 for i in range(5): name=input("name:") #姓名 cj=random.randint(50,100) #成绩 cjb.append([name,cj]) print(cjb) print(pickle.dumps(cjb)) #序列化的bytes对象 print(type(pickle.dumps(cjb))) #class 'bytes' #将成绩表中的数据保存到cjb.txt文件中 with open('cjb.txt','wb')as f: f.write(pickle.dumps(cjb)) print("结果已保存") 结果如下: name:1 name:2 name:3 name: name:4 [['1', 91], ['2', 56], ['3', 88], ['', 67], ['4', 93]] b'\x80\x03]q\x00(]q\x01(X\x01\x00\x00\x001q\x02K[e]q\x03(X\x01\x00\x00\x002q\x04K8e]q\x05(X\x01\x00\x00\x003q\x06KXe]q\x07(X\x00\x00\x00\x00q\x08KCe]q\t(X\x01\x00\x00\x004q\nK]ee.'
结果已保存
(2)反序列化操作:
反序列化方法1:pickle.load()
格式为:pickle.load(file)
该方法是将序列化的对象从文件file中读取出来。关于文件file,必须是以二进制的形式进行操作(读取)。
示例如下:与上面的例子一样,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中;再次运行程序时,读取cjb.txt中的学生信息,进行加载,再次写入数据时,以追加的方式写入。
import random import pickle #如果没有cjb,就让cjb=[],如果存在,就将内容读取出来 try: with open('cjb.txt','rb')as f: cjb=pickle.load(f) print(cjb) print("结果已加载") except: cjb=[] #写入5个学生的数据到成绩表中 for i in range(5): name=input("name:") #姓名 cj=random.randint(50,100) #成绩 cjb.append([name,cj]) print(cjb) #将成绩表中的数据保存到cjb.txt文件中 with open('cjb.txt','wb')as f: pickle.dump(cjb,f) print("结果已保存") 结果如下: [['1', 73], ['2', 60], ['3', 81], ['4', 87], ['5', 95], ['q', 83], ['w', 91], ['e', 88], ['rt', 85], ['t', 72]] 结果已加载 name:a name:b name:c name:d name:e [['1', 73], ['2', 60], ['3', 81], ['4', 87], ['5', 95], ['q', 83], ['w', 91], ['e', 88], ['rt', 85], ['t', 72], ['a', 54], ['b', 83], ['c', 70], ['d', 97], ['e', 67]] 结果已保存
反序列化方法2:pickle.loads()
格式为:pickle.loads()
pickle.loads()方法跟pickle.load()方法不同:pickle.loads()方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。下面的例子是将信息保存到了文件中,所以要从文件中读取,以pickle.loads(f.read())的方式读取。
示例如下:与上面的例子一样,将五个学生的成绩写入到成绩表中,保存在cjb.txt文件中;再次运行程序时,读取cjb.txt中的学生信息,进行加载,再次写入数据时,以追加的方式写入。
import random import pickle #如果没有cjb,就让cjb=[],如果存在,就将内容读取出来 try: with open('cjb.txt','rb')as f: cjb=pickle.loads(f.read()) print(cjb) print("结果已加载") except: cjb=[] #写入5个学生的数据到成绩表中 for i in range(5): name=input("name:") #姓名 cj=random.randint(50,100) #成绩 cjb.append([name,cj]) print(cjb) #将成绩表中的数据保存到cjb.txt文件中 with open('cjb.txt','wb')as f: f.write(pickle.dumps(cjb)) print("结果已保存") 结果如下: [['1', 87], ['2', 59], ['3', 78], ['4', 77], ['5', 75]] 结果已加载 name:a name:b name:c name:d name:e [['1', 87], ['2', 59], ['3', 78], ['4', 77], ['5', 75], ['a', 55], ['b', 86], ['c', 86], ['d', 61], ['e', 67]] 结果已保存