json 与 pickle 模块 - 图1


json 模块

json简介

  1. 1json格式是什么
  2. # 把python中的字典,列表..数据类型转成json格式字符串
  3. # 下面格式是标准的json格式字符串
  4. {"name":"xio","age":18,"handsome":true,"xx":null}
  5. 2json格式有什么用?
  6. # 存取数据(格式标准),一个程序写入,另一个程序读取(这两个程序可以是不同的语言)
  7. # 后端给前端的数据是json格式字符串
  8. 3python中如何使用json
  9. #序列化:把某个语言的变量转成json格式字符串
  10. #反序列化:把json格式字符串转成某个语言的变量
  11. # 补充:java中,出于性能的考虑,有很多包来完成序列化和反序列化:谷歌的gson 阿里开源fastjson

dumps

  1. import json # 导入json模块,内置模块
  2. # 序列化
  3. # 定义一个字典
  4. dic = {'name': 'xio', 'age': 18, 'handsome': True, 'xxx': None}
  5. # 把字典转成json格式字符串
  6. dic_str=json.dumps(dic)
  7. print(dic_str) # {"name": "xio", "age": 18, "handsome": true, "xxx": null}
  8. print(type(dic_str)) # <class 'str'>

loads

  1. import json
  2. # 反序列化
  3. s='''
  4. {"name": "xio", "age": 18, "handsome": true, "xxx": null}
  5. '''
  6. # 把json格式字符串反序列化成字典
  7. s_dic=json.loads(s)
  8. print(s_dic) # {'name': 'xio', 'age': 18, 'handsome': True, 'xxx': None}
  9. print(type(s_dic)) # <class 'dict'>
  1. # json模块可以序列化:字典,列表,布尔
  2. # 稍微复杂点的字典+列表格式+布尔格式
  3. dic = {'movieIds': [111, 222, 333, 444],
  4. 'stids': [{'movieId': 11, 'stid': 1}, {'movieId': 22, 'stid': 2}, {'movieId': 33, 'stid': 3}]}
  5. res = json.dumps(dic)
  6. print(res)
  7. # {"movieIds": [111, 222, 333, 444], "stids": [{"movieId": 11, "stid": 1}, {"movieId": 22, "stid": 2}, {"movieId": 33, "stid": 3}]}

dump、load 文件应用

  1. import json
  2. # 序列化和反序列化放到文件中
  3. # 土办法
  4. dic = {'name': 'xio', 'age': 18, 'handsome': True, 'xxx': None}
  5. dic_str = json.dumps(dic)
  6. print(dic_str)
  7. with open('a.json', 'wt', encoding='utf-8') as f:
  8. f.write(dic_str)
  9. # 序列化的简化写法
  10. dic = {'name': 'xio', 'age': 18, 'handsome': True, 'xxx': None}
  11. with open('a.json', 'wt', encoding='utf-8') as f:
  12. json.dump(dic, f)
  13. # 反序列化的简化写法
  14. with open('a.json', 'rt', encoding='utf-8') as f:
  15. dic = json.load(f)
  16. print(dic)
  17. print(type(dic))

补充:ensure_ascii=False

  1. import json
  2. dic = {'name': '小蜗', 'age': 18, 'handsome': True, 'xxx': None}
  3. print(json.dumps(dic,ensure_ascii=False))
  4. # {"name": "小蜗", "age": 18, "handsome": true, "xxx": null}
  5. print(json.dumps(dic))
  6. # {"name": "\u5c0f\u8717", "age": 18, "handsome": true, "xxx": null}

pickle 模块

pickle 序列化与反序列化

  1. import pickle # 内置模块
  2. # pickle序列化
  3. dic={'name':'xio','age':18}
  4. res=pickle.dumps(dic)
  5. print(res)
  6. #b'\x80\x04\x95\x1a\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x03xio\x94\x8c\x03age\x94K\x12u.'
  7. # pickle的反序列化
  8. b = b'\x80\x04\x95\x1a\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x03xio\x94\x8c\x03age\x94K\x12u.'
  9. res = pickle.loads(b)
  10. print(res) # {'name': 'xio', 'age': 18}
  11. print(type(res)) # <class 'dict'>

文件+序列化和反序列化

  1. import pickle
  2. # 文件+序列化和反序列化
  3. dic = {'name': 'xio', 'age': 18}
  4. with open('a.pkl', 'wb') as f:
  5. pickle.dump(dic, f)
  6. with open('a.pkl', 'rb') as f:
  7. res = pickle.load(f)
  8. print(res)

比较pickle和json

  1. '''
  2. json:通用格式,任何语言都有,都可以解析,但是数据类型有限
  3. pickle:只是python使用,转成b格式,其它语言识别不了,任意的数据类型都可以
  4. '''
  5. import json
  6. import pickle
  7. dic = {'a': input}
  8. res = json.dumps(dic) # 报错
  9. res1 = pickle.dumps(dic)
  10. # b'\x80\x04\x95\x1d\x00\x00\x00\x00\x00\x00\x00}\x94\x8c\x01a\x94\x8c\x08builtins\x94\x8c\x05input\x94\x93\x94s.'
  11. print(res)
  12. dic_2 = pickle.loads(res1)
  13. dic_2['a']() # 相当于调用了input功能

猴子补丁

  1. # 一.什么是猴子补丁?
  2. 属性在运行时的动态替换,叫做猴子补丁(Monkey Patch)。
  3. 猴子补丁的核心就是用自己的代码替换所用模块的源代码,详细地如下
  4.   1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
  5.   2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch
  6. # 二. 猴子补丁的功能(一切皆对象)
  7.   1.拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)
  8. class Monkey:
  9. def hello(self):
  10. print('hello')
  11. def world(self):
  12. print('world')
  13. def other_func():
  14. print("from other_func")
  15. monkey = Monkey()
  16. monkey.hello = monkey.world
  17. monkey.hello()
  18. monkey.world = other_func
  19. monkey.world()
  20. # 三.monkey patch的应用场景
  21. 如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高,
  22. 但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能
  23. 会想到这么做
  24. import ujson as json,但是这么做的需要每个文件都重新导入一下,维护成本依然很高
  25. 此时我们就可以用到猴子补丁了
  26. 只需要在入口处加上
  27. , 只需要在入口加上:
  28. import json
  29. import ujson
  30. def monkey_patch_json():
  31. json.__name__ = 'ujson'
  32. json.dumps = ujson.dumps
  33. json.loads = ujson.loads
  34. monkey_patch_json() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果
  35. #其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey
  36. Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey
  37. Patch带了便利的同时也有搞乱源代码的风险!