Hello,大家好,我是景天,今天来根大家聊一聊python的序列化与反序列化
Python语言的序列化与反序列化可用pickle和json模块
1、pickle 序列化/反序列化模块
pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,
pickle序列化后的数据,可读性差,人一般无法识别。
import pickle
序列化: 把不能够直接存储在文件中的数据变得可存储
反序列化: 把存储在文件中的数据拿出来恢复成原来的数据类型
php
serialize
unserialize
所有的数据类型都通过pickle模块进行序列化
lst = [1,2,3] #错误案例, 文件不能直接存储容器 ,数字,图片,音视频等类型数据, 文件只能存储字符串和字节流 with open("lianxi1.txt",mode="w",encoding="utf-8") as fp: fp.write(1)
1 dumps 把任意对象序列化成一个bytes
res = pickle.dumps(lst) print(res , type(res))
序列化之后,就可以将数据存储在文件,但要使用字节流模式
#函数可以序列化么? 可以
def func(): print("我是func函数") res = pickle.dumps(func) print(res , type(res))
#迭代器可以序列化么? 可以
it = iter(range(10)) res = pickle.dumps(it) print(res , type(res))
2 loads 把任意bytes反序列化成原来数据
res2 = pickle.loads(res) print(res2 , type(res2))
3 直接跟文件有关的操作
1 dump 把对象序列化后写入到file-like Object(即文件对象)
dump既可以直接将数据对象序列化,也可以将字节流序列化写入文件对象
lst = [1,2,3] with open("lianxi1.txt",mode="wb") as fp: pickle.dump(lst,fp)
2 load 把file-like Object(即文件对象)中的内容拿出来,反序列化成原来数据
with open("lianxi1.txt",mode="rb") as fp: res2 = pickle.load(fp) print(res2 , type(res2))
3 dumps 和 loads 对文件进行写入读取字节流操作
#写入字节流 with open("lianxi2.txt",mode="wb+") as fp: res1 = pickle.dumps(lst) fp.write(res1) #读取字节流 with open("lianxi2.txt",mode="rb+") as fp: bytes_str = fp.read() res = pickle.loads(bytes_str) print(res , type(res2))
#dumps,loads和dump,load使用方式:
如果应用场景和文件有关,使用dump,load
如果没关,使用dumps,loads
2、json 序列化/反序列化模块
import json
json格式的数据, 所有的编程语言都能识别,本身是字符串 一共能存8个类型
能够转化的类型有要求: int float bool str list tuple dict Non
json 主要应用于传输数据 , 序列化成字符串
pickle 主要应用于存储数据 , 序列化成二进制字节流
集合和complex格式 不支持json序列化
1 json 基本用法
#json => dumps 和 loads
参数
sort_keys =True 是告诉编码器按照字典排序(a到z)输出。如果是字典类型的python对象,就把关键字按照字典排序
“”“ensure_ascii=False 可以包含非ASCII字符,显示中文 sort_keys=True 字典按键排序”“”
如果不设置ensure_ascii=False 默认中文以unicode的编码显示
dic = {"name":"梁新宇","sex":"野味","age":22,"family":["爸爸","妈妈","姐姐"]} res = json.dumps(dic,ensure_ascii=False,sort_keys=True) print(res , type(res)) dic = json.loads(res) print(dic , type(dic))
dumps 序列化,将其它数据类型转化为字符串
loads 反序列化,将字符串还原成原有数据类型
dumps和loads写入文件和读取:
json.dumps() 方法 将一个Python数据结构转换为JSON字符串
常用参数如下:
这样的格式一般都不优美,当数据很多的时候,看得就不是很直观方便。
可以使用indent=4 参数来对json进行数据格式化输出,会根据数据格式缩进显示,读起来更加清晰
用法如下
import json data = [{"name":"张","age":20},{"name":"王","age":21}] json_str=json.dumps(data, indent=4, ensure_ascii=False) print(json_str)
separators=(',', ':') dumps出来的字典 值的前面不带空格
#json => dump 和 load 和文件相关
with open("lianxi3.json",mode="w",encoding="utf-8") as fp: json.dump(dic,fp,ensure_ascii=False) with open("lianxi3.json",mode="r",encoding="utf-8") as fp: dic = json.load(fp) print(dic , type(dic))
2 json 和 pickle 之间的区别
#1.json
json 连续dump数据 , 但是不能连续load数据 , 是一次性获取所有内容进行反序列化.
dic1 = {"a":1,"b":2} dic2 = {"c":3,"d":4} with open("lianxi4.json",mode="w",encoding="utf-8") as fp: json.dump(dic1,fp) fp.write("\n") json.dump(dic2,fp) fp.write("\n")
可以连续dump
不能连续load,超过一次dump的数据,load就会报错。是一次性获取所有数据 , error。load是一次性地将所有数据放在一块反序列化,解码解不出来
with open("lianxi4.json",mode="r",encoding="utf-8") as fp: dic = json.load(fp) #解决办法 loads(分开读取)。前提是数据必须换行,不换行loads也不行 with open("lianxi4.json",mode="r",encoding="utf-8") as fp: for line in fp: dic = json.loads(line) print(dic,type(dic))
写入文件的数据不换行,用loads也不行
#2.pickle
import pickle #pickle => dump 和 load **pickle 连续dump数据,也可以连续load数据** with open("lianxi5.pkl",mode="wb") as fp: pickle.dump(dic1,fp) pickle.dump(dic2,fp) pickle.dump(dic1,fp) pickle.dump(dic2,fp)
#方法一
with open("lianxi5.pkl",mode="rb") as fp: dic1 = pickle.load(fp) dic2 = pickle.load(fp) print(dic1) print(dic2)
pickle的dump几次,就load几次,可以连续load不报错,是因为字节流有结束符
#方法二 (扩展)
try … except … 把有可能报错的代码放到try代码块中,如果出现异常执行except分支,来抑制报错
#一次性拿出所有load出来的文件数据
try: with open("lianxi5.pkl",mode="rb") as fp: while True: dic = pickle.load(fp) print(dic) except: pass
总结:
son 和 pickle 两个模块的区别:
(1)json序列化之后的数据类型是str,所有编程语言都识别,
但是仅限于(int float bool)(str list tuple dict None)
json不能连续load,只能一次性拿出所有数据
(2)pickle序列化之后的数据类型是bytes,用于数据存储
所有数据类型都可转化,但仅限于python之间的存储传输.
pickle可以连续load,多套数据放到同一个文件中
pickle自己用可以,用的前提是大家都支持pickle