json & pickle模块
1. 什么是序列化
-
序列化是指把内存的数据类型转换成一个特定的格式内容,该格式的内容可用于存储或者传输给其他平台使用
-
内存中的数据类型——>序列化——>特定的格式(json格式或者pickle格式)
-
内存中的数据类型<——反序列化<——特定的格式(json格式或者pickle格式)
''' {'aaa': 111}——>序列化str({'aaa': 111})——>"{'aaa':111}" {'aaa': 111}<——反序列化eval("{'aaa':111}")<——"{'aaa':111}" '''
2. 为何要序列化
-
序列化得到结果——>特定的格式的内容有两种用途
-
1、可用于存储===>用于存档
-
2、传输给其他平台使用===>跨平台数据交互
''' python java 列表 特定的格式 数组 强调: 针对用途1的特定格式:可以是一种专用的格式——> pickle只有python可以识别 针对用途2的特定格式:应该是一种通用的,能够被所有语言识别的格式——> json '''
3. 序列化与反序列化的使用
# 序列化 import json # 序列化的复杂方法 json_res = json.dumps([1, 'aa', True, False, [1, 2, 3], {'b': 11}]) with open(r'test.json', 'wt', encoding='utf-8') as f: f.write(json_res) # 序列化简单方法 with open(r'test.json', 'wt', encoding='utf-8') as f: json.dump([1, 'aa', True, False, [1, 2, 3], {'b': 11}], f) # 反序列化 # 反序列化的复杂方法 with open(r'test.json', 'rt', encoding='utf-8') as f: json_res = f.read() loads_res = json.loads(json_res) print(loads_res) # 反序列化的简单方法 with open(r'test.json', 'rt', encoding='utf-8') as f: loads_res = json.load(f) print(loads_res) # json验证:json格式兼容的是所有语言通用的数据类型,不能使用独有的数据类型 json.dumps({1,2,3}) # 集合为python独有数据类型 # json强调:一定要搞清楚json格式,不能与python混淆 l = json.loads('[1, "aaa", true, false]') print(l) # 结果:[1, 'aaa', True, False] # 在python解释器2.7与3.6之后都可以json.loads(bytes类型),但唯独3.5不可以 res=json.dumps({'name':'哈哈哈'}) print(res,type(res)) res=json.loads('{"name": "\u54c8\u54c8\u54c8"}') print(res,type(res))
4. 猴子补丁与ujson
-
4.1 什么是猴子补丁
- 猴子补丁的核心就是用自己的代码替换所用模块的源代码
-
4.2 猴子补丁的功能(一切皆对象)
- 拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)
- 4.3 monkey patch的应用场景
''' 如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高, 但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能 会想到这么做 ''' 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() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果 #其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey Patch带了便利的同时也有搞乱源代码的风险!
5. pickle模块
import pickle res = pickle.dumps({1, 2, 3, 4, 5}) print(res, type( res)) # b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8f\x94(K\x01K\x02K\x03K\x04K\x05\x90.' <class 'bytes'> res1 = pickle.loads(res) print(res1, type(res1)) # {1, 2, 3, 4, 5} <class 'set'> # pickle的序列化与反序列化 f = open('序列化对象_pickle', 'wb') # 注意是w是写入str,wb是写入bytes,j是'bytes' f.write(j) # ------------------等价于pickle.dump(dic,f) f.close() # 反序列化 import pickle f = open('序列化对象_pickle', 'rb') data = pickle.loads(f.read()) # 等价于data=pickle.load(f) print(data['age']) # python2与python3的pickle兼容性问题 # coding:utf-8 import pickle with open('a.pkl', mode='wb') as f: # 一:在python3中执行的序列化操作如何兼容python2 # python2不支持protocol>2,默认python3中protocol=4 # 所以在python3中dump操作应该指定protocol=2 pickle.dump('你好啊', f, protocol=2) with open('a.pkl', mode='rb') as f: # 二:python2中反序列化才能正常使用 res = pickle.load(f) print(res)

浙公网安备 33010602011771号