1. 模块的介绍
在介绍pickle模块之前,我们先了解一下python中的模块以及模块的分类,可以让我们对模块有更深入的了解。
(1) 模块是什么:
- Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
- 模块让你能够有逻辑地组织你的 Python 代码段。
- 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
- 模块能定义函数,类和变量,模块里也能包含可执行的代码。
- 它可以被其他程序引用,从而使用该模块里的函数等功能,使用Python中的标准库也是采用这种方法。
(2) 模块的分类:
在Python中,模块分为以下几种:
- 系统内置模块:例如:sys、time、json模块等等,安装好python之后通过导入模块的形式就可以直接使用;
- 自定义模块:自定义模块是自己写的模块,对某段逻辑或某些函数进行封装后供其他函数调用。(注意:自定义模块的命名一定不能和系统内置的模块重名了,否则将不能再导入系统的内置模块)。例如:自定义了一个os.py模块后,就不能再使用python中内置的模块;
- 第三方的开源模块:这部分模块可以通过 pip install 模块名 进行安装,有开源的代码;
2. pickle模块的介绍
(1)pickle模块:
pickle模块是python语言的一个系统内置模块,安装python后已包含pickle库,不需要单独再安装。
(2)pickle模块的特点:
1、只能在python中使用,只支持python的基本数据类型,是python独有的模块。
2、序列化的时候,只是序列化了整个序列对象,而不是内存地址。
3、pickle有两类主要的接口,即序列化和反序列化;
通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;
通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
(3)为什么需要序列化和反序列化操作呢?
1、便于存储
序列化过程是将Python程序运行中得到了一些字符串、列表、字典等数据信息转变为二进制数据流。这样信息就容易存储在硬盘之中,当需要读取文件的时候,从硬盘中读取数据,然后再将其反序列化便可以得到原始的数据。
2、便于传输
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把对象转换为字节序列,在网络上传输;接收方则需要把字节序列在恢复为对象,得到原始的数据。
3. pickle模块的使用
(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.'
- <class 'bytes'>
- 结果已保存
(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]]
- 结果已保存