为什么序列化:
内存中的字典、列表、集合以及各种对象及自己定义的类的实例,如何保存到一个文件中?
如何从文件中读取数据,并让它们在内存中再次恢复成自己对应的类的实例?
要设计一套协议,按照某种规则,把内存中数据保存到文件中。
文件是一个字节序列,所以必须把数据转换成字节序列,输出到文件。这就是序列化。
反之,从文件的字节序列恢复到内存并且还是原来的类型,就是反序列化。
定义:
序列化(pickling):我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化
反序列化(unpickling):把变量内容从序列化的对象重新读到内存里称之为反序列化
从文件的字节序列恢复到内存,为反序列化。
序列化保存到文件就是持久化。
可以将数据序列化后持久化,或者网络传输;也可以将从文件中或者网络接收到的字节序列反序列化。
可以序列化的一定可以反序列化。
pickle模块
python中的序列化、反序列化模块
序列化:将python对象及所有层次结构转化为字节流的过程,即:将内存中对象存储下来,把它变成一个个字节–>二进制
把内存中的数据,变成字节流称为序列化,按某种规则,把内存中的数据保存到文件中(保存只是顺带,序列化保存到文件,保存过程称为持久化)
文件是一个字节序列,所以必须把数据转换成字节序列,输出到文件。—>序列化(文件存储过程为序列化过程)
反序列化:将字节流转为为python对象层次结构,即:将文件的一个个字节恢复成内存中对象(二进制恢复为有类型的对象)<–二进制。
支持python对象:
【适用所有的数据类型list dict 集合 类】
可存储的数据类型
1、所有基本类型:int、float、complex、str、bytes、bytearray、True、False、None
2、由 基本类型中数据组成的 list、tuple、dict、set
3、在模块顶层定义的函数(使用 def 定义)、内置函数、类和类的实例
常用方法:
dumps 对象序列化为bytes对象 (不存入文件)
dump 对象序列化到文件对象,就是存入文件
loads 从bytes对象反序列化 (从内存中装载)
load 对象反序列化,从文件读取数据
常用方法解析
pickle.dump(obj, file, protocol=None, fix_imports=True)
功能:将 obj 以字节的形式写入 file
参数:
obj:表示要序列化的对象
file:表示 obj 要写入的文件对象,file 必须以二进制可写模式打开,即 'wb'
protocol:表示告知 pickler 使用的协议,支持的协议有 0,1,2,3,默认的协议是协议 3
fix_imports:如果 fix_imports 为 True 并且协议小于 3,则 pickle 将尝试将新的 Python 3名称映射到 Python 2中使用的旧模块名称,以便 pickle 数据流可被Python 2读取
返回值:None
dumps(obj, protocol=None, fix_imports=True)
功能:以字节对象形式返回序列化的对象,不需要写入文件中
参数:各参数含义与 dump() 中相同
返回值:一个 bytes 对象
load(file, fix_imports=True, encoding='ASCII', errors='strict')
功能:从 file 中读取数据并返回给 Python 对象
参数:file:表示一个以二进制可读模式(即 'rb')打开的文件对象
返回值:相应的对象
说明:另外三个可选参数用于控制对 Python 2生成的 pickle 流的兼容性支持
loads(bytes_object, fix_imports=True, encoding='ASCII', errors='strict')
功能:从字节对象中读取被序列化的对象,并返回
参数:bytes_object 表示一个字节对象
返回值:相应的对象
常见内建数据类型序列化/反序列化(只保留了数据,未保存属性)
dump/load
# import pickle
# filename = 'E:/testA'
# x = 'a'
# y = 100
# z = '100'
# m = {'a':x, 'b':y, 'c':z}
# with open(filename, 'wb') as f: #以二进制的方式写入 ASCII码
# # pickle.dump(x, f)
# # pickle.dump(y, f)
# # pickle.dump(z, f)
# pickle.dump(m, f)
#反序列化
# with open(filename, 'rb') as f: #以二进制的方式读取
# # for _ in range(3):
# for _ in range(1):
# a = pickle.load(f)
# print(a,type(a))
dumps/loads
# import pickle
# filename = 'E:/testA'
# x = 'a'
# y = 100
# z = '100'
# i = ['abc']
# m = {'a':x, 'b':y, 'c':z}
# with open(filename, 'wb') as f:
# n = pickle.dumps(m) #转换成二进制类型
# print(n,type(n))
#
# with open(filename, 'rb') as f: #以二进制的方式读取
# for _ in range(1): #反序列化的数量与序列化数量保持一致
# a = pickle.loads(n)
# print(a,type(a))
# # a.keys()
# # print(a.keys())
# # print(a.values())
多个值序列化
# import pickle
# filename = 'E:/testA'
# x =['a',100,'100',['abc'],{'a':1, 'b':2, 'c':3}]
#
# lst=[]
# with open(filename, 'wb') as f:
# for i in x:
# lst.append(pickle.dumps(i)) #转换成二进制类型,不写入文件
#
# # n=pickle.dumps(x)
# # print(n,type(n))
#
# with open(filename, 'rb') as f: #以二进制的方式读取
# for i in lst:
# a = pickle.loads(i)
# print(a,type(a))
# a = pickle.loads(n)
# print(a, type(a))
对象序列化
# import pickle
# class AAA: #类的定义
#
# def __init__(self): #初始化方法
# self.ttt = 'abc' #定义属性ttt 保存对象的属性
# def show(self):
# self.bbb= '123'
# print(123) #非特殊属性
# a1 = AAA() #任何一个对象都是类型的实例,创建一个对象
# print(a1.ttt)
# 对象序列化
# filename = 'E:/testA'
# with open(filename, 'wb') as f:
# b = pickle.dumps(a1)
# print(b,type(b))
#
# #反序列化
# with open(filename, 'rb') as f:
# b1 =pickle.loads(b) #object AAA的对象--》实例
# print(b1,type(b1))
# print(b1.ttt)
# b1.show()
输出到文件
#输出到文件 需要两边代码一致:定义一直
class AAA: #类的定义
def __init__(self): #初始化方法
self.ttt = 'abc' #定义属性ttt 保存对象的属性
a1 = AAA() #任何一个对象都是类型的实例,创建一个对象
print(a1.ttt)
filename = 'E:/testA'
with open(filename, 'wb') as f:
pickle.dump(a1, f)
with open(filename, 'rb') as f:
x1 = pickle.load(f)
print(x1,type(x1))
print(x1.ttt)
注意:文件对象不可进行序列化
pickle库好处:pickle文件格式独立于机器的体系结构,不分操作系统