序列化与反序列化
序列化与反序列化
- 最近在读麦叔的“python3分钟”,麦叔花了4篇的篇幅来介绍序列化与反序列化,加之本来对序列化的理解就比较含糊,因此今天打算系统的把序列化与反序列化梳理一遍。
引言
-
序列化:把对象转成字节数组的所制定的规则就叫序列化,或者说序列化只是一种拆装组装对象的规则,其实也就是转化成字符串,方便存储
-
反序列化:从IO流里面读出数据的时候再以这种规则把对象还原回来就叫做反序列化
- 对象序列化
- 狭义:对象序列化是指把一些内存中的对象转变成字节流,以便保存到文件或者通过网络传输。等以后再通过反序列化转变成内存中的对象
- 广义:把对象转换成JSON,CSV等数据格式也被称为序列化
- 对象序列化
-
目的:
- 便于对象可以跨平台存储,和进行网络传输
-
常见的序列化方式:JDK(不支持跨语言)、JSON、XML、Hessian、Kryo(不支持跨语言)、Thrift、Protostuff、FST(不支持跨语言)
-
应用场景
- 把对象转换成JSON或XML格式,方便网络传输,通常是使用Rest API传输
- 把对象转成字节流,方便远程方法调用(其实这种方法用的越来越少,因为大部分人会使用第一种方法中的API)
- 把对象转换成字节流保存到硬盘,以便下次回来可以继续
python中的序列化的方式
-
Python中提供pickle和json两个模块来实现序列化与反序列化,pickle模块和json模块dumps()、dump()、loads()、load()这是个函数,其中dumps()、dump()用于实现序列化,loads()、load()用于实现反序列化
-
pickle和json的区别
- json 所有语言通用;只能序列化基本内容,输出的类型为字符型
- pickle对于python中的所有东西均能被序列化(socket对象除外)序列化的内容只有python认识,缺点:不可读,pickle输出的字符类型为types
pickle序列化
-
pickle是Python自带库,可以把对象转成字节流
-
pickle模块的dumps()、dump()、loads()、load()是个函数按功能划分可以分为两组:
序列化:dumps()、dump()
反序列化:loads()、load()
-
dumps()与dump()的区别是dumps()只是单纯得将对象序列化,而dump()会在序列化之后将结果写入到文件当中;与之对应,loads()与load()区别至于loads()是对dumps的序列化结果进行反序列化,而dump()会从文件中读取内容进行反序列化。
#********************************>>>>>dumps()/loads()<<<<<*******************************
#利用pickle模块对集合进行序列化与反序列化
v = {1,2,3,3}
import pickle
val = pickle.dumps(v)
print (val)
data = pickle.loads(val)
print(data)
#元组作为一个元素同样是可行的
v = (1,2,3,3,[1,2,3])
import pickle
val = pickle.dumps(v)
print (val)
data = pickle.loads(val)
print(data)
#利用pickle对函数进行序列化与反序列化
def func():
print("yang")
import pickle
v1 = pickle.dumps(func)
v2 = pickle.loads(v1)
print(v1,v2,sep = "\n") #sep:同时打印两个对象时进行换行
#********************************>>>>>dump()/load()<<<<<*******************************
class Food:
def __init__(self, name, origin, calories, price):
self.name = name
self.origin = origin #产地
self.calories = calories #卡路里
self.price = price
print('...此处省略2500行推荐算法代码...')
food1 = Food('胡辣汤', '山东', 25, 2)
food2 = Food('油条', '山东', 88, 1)
food3 = Food('豆腐脑', '山东', 35, 2.5)
food4 = Food('焖饼', '山东', 65, 10)
recommend = [food1, food2, food3, food4]
import pickle
with open("foods.pickle", "wb") as file:#打开一个新文件file,由于是字节流,必须是wb,模式的
pickle.dump(recommend, file)
#进行反序列化
with open("foods.pickle", "rb") as out:
remote_recommend = pickle.load(out)
print(remote_recommend)
json序列化
- json序列化之后得到的是json格式字符串JSON就这样通过大括号、方括号、键值对以及对象的嵌套,可以表达几乎任何复杂的数据
- json序列化指的是,将python数据类型转化为json类型,不支持元组和*集合8进行序列化
#将对象序列化dumps
food = [
{'name':'jame', 'origin':'Italy'},
{'name':'hamburger', 'origin':'UK'},
]
import json
# 把对象转成JSON字符串
food_json = json.dumps(food)
print(f'检查一下food_json的类型,是字符串:{type(food_json)}')
print('打印一下结果:')
print(food_json)
# 把JSON字符串转成对象
from_json = json.loads(food_json)
print(f'看一下类型,应该是列表:{type(from_json)}')
#当要序列化的对象中含有中文字符时,json.dumps()序列化时便不会解码,出现乱码
food = [
{'name':'样子', 'origin':'Italy'},
{'name':'hamburger', 'origin':'UK'},
]
import json
# 把对象转成JSON字符串
food_json = json.dumps(food)
print(food_json)
'''
[{"name": "\u6837\u5b50", "origin": "Italy"}, {"name": "hamburger", "origin": "UK"}]
'''
#此时应该在dump添加参数ensure_ascii=False
json.dumps(food, ensure_ascii=False)
#json不支持*元组*和*集合进行序列化
v1 = [11,'yang',[11,22,33],{'k':5},True,("yang","zi")]
#当对象中含有元组时在序列化的时候会将其自动变为列表,当含有集合的时候就会报错
import json
v2 = json.dumps(v1)
print(v2,type(v2))
'''
输出结果
[11, "yang", [11, 22, 33], {"k": 5}, true, ["yang", "zi"]] <class 'str'>
'''
#*****************************************json.dump/loads**************************************************
#序列化后并写入一个指定的文件,
f = open('x.txt',mode='w',encoding ="utf-8")
v = ('杨子列','杨驰',[1,2,3])
import json
val = json.dump(v,f)
print(val)
f = open('x.txt',mode='r',encoding ="utf-8")
import json
val = json.load(f)
f.close()
print(val)
就在如何将python中的对象或者方法利用json直接进行序列化的情况,麦叔在三分钟的25—28处给出了较为详细的方法,随着学习的深入要回过头来再补充.........
记录学习的点点滴滴