目录
一、序列化
(一)序列化与反序列化
把对象从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等。
内存中的数据类型---->序列化---->特定的格式(json格式或者pickle格式)
内存中的数据类型<----反序列化<----特定的格式(json格式或者pickle格式)
(二)为什么需要序列化
1、用于存储
内存是无法永久保存数据的,当程序运行一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据都被清空了。
在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。例如,虚拟机状态的挂起、游戏存档等。
2、传输给其他平台使用
序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用一种序列化的格式,那么便打破了平台、语言差异化带来的限制,实现了跨平台数据交互。
二、json模块
(一)、json实现序列化和反序列化
import json
# 序列化
json_res = json.dumps([123, 'xhj', True, False])
print(json_res, type(json_res))
# 反序列化
l = json.loads(json_res)
print(l, type(l))
(二)、序列化结果写入文件
1、基本方式
import json
json_res=json.dumps([123,'xhj',True,False])
with open('test.json',mode='wt',encoding='utf-8') as f:
f.write(json_res)
2、json.dump
import json
with open('test.json',mode='wt',encoding='utf-8') as f:
json.dump([123,'xhj',True,False],f)
(三)、从文件读取序列化结果进行反序列化操作
1、基本方式
import json
with open('test.json',mode='rt',encoding='utf-8') as f:
json_res=f.read()
l=json.loads(json_res)
print(l,type(l))
2、json.load
import json
with open('test.json',mode='rt',encoding='utf-8') as f:
l=json.load(f)
print(l,type(l))
(四)、猴子补丁
1、什么是猴子补丁
属性在运行时的动态替换,叫做猴子补丁(Monkey Patch)。猴子补丁的核心就是用自己的代码替换所用模块的源代码:
- 这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
- 还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。
2、应用场景
如果我们程序基于json写了大量代码,但这时我们发现一个ujson模块更高效,这时我们首先想到的改进措施是
import ujson as json
但这样做每个程序都要改一遍,维护成本比较高,这时我们便可以使用猴子补丁了。
# 在入口处打猴子补丁
import json
import ujson
def monkey_patch_json():
json.__name__ = 'ujson'
json.dumps = ujson.dumps
json.loads = ujson.loads
monkey_patch_json() # 在入口文件处运行
(五)、注意
- 无论数据怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads。
- 在python解释器2.7与3.6之后都可以json.loads(bytes类型),但唯独3.5不可以,会产生TypeError: the JSON object must be str, not 'bytes'。
三、pickle模块
与json模块功能类似,但pickle模块只能用于python程序间传数据或者python对象的持久化。
import pickle
res = pickle.dumps(['xhj',123,'abc'])
print(res, type(res))
s = pickle.loads(res)
print(s, type(s))