json|pickle|猴子补丁

2020-09-09  本文已影响0人  阿登20

json

1、序列化:将内存数据转成字符串加以保存。dumps
2、反序列化:将字符串转成内存数据加以读取。loads

image.png

JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

image.png image.png
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
# @Time : 2020/9/9 16:13
# @File  : json_.py
# @Author: adeng
# @Date  : 2020/9/9
============================
"""

"""
1、序列化:将内存数据转成字符串加以保存。
2、反序列化:将字符串转成内存数据加以读取。
"""
import json

# 1. 对象结构
data_json = '{"status":1,"code":"10001","data":null,"msg":"登录成功"}'

# 将json格式的数据转化为python中的字典类型
# loads 可以将json格式的字符串转化成字典类型

data_dict = json.loads(data_json)
print(data_dict)  # {'status': 1, 'code': '10001', 'data': None, 'msg': '登录成功'}

# 将python中字典的类型转化为json字符串
# dumps 可以将字典类型转化为json格式的字符串
one_dict = {'name': '阿登', 'age': '18', 'hobby': None, 10: True}
json_str = json.dumps(one_dict, ensure_ascii=False)
# json格式字符串里面的字典的key是双引号字符串  空是 null 布尔是小写
# 如何记忆 宕机 将字典转化为json


# 2. 数组结构

data_json_1 = '[{"status":1,"code":"10001","data":null,"msg":"登录成功"},' \
              '{"status":2,"code":"10001","data":null,"msg":"登录成功"},' \
              '{"status":3,"code":"10001","data":null,"msg":"登录成功"}]'

nested_dict_list = json.loads(data_json_1)
print(nested_dict_list)

two_dict = [{'status': 1, 'code': '10001', 'data': None, 'msg': '登录成功'},
            {'status': 2, 'code': '10001', 'data': None, 'msg': '登录成功'},
            {'status': 3, 'code': '10001', 'data': None, 'msg': '登录成功'}
            ]
# 将嵌套字典的列表转换成 json格式的字符串
json_str_1 = json.dumps(two_dict, ensure_ascii=False)
# json数据在python呈现是以字符串呈现的,可以是对象结构,也有数组结构
pass

# 从文件中读取json格式的数据,用load
# loads是传字符串类型 load是传文件类型
# one_json_file.txt.txt 文件数据是json格式的内容为: {"status":1,"code":"10001","data":null,"msg":"登录成功"}

with open("one_json_file.txt", encoding="utf8") as one_file:
    there_dict = json.load(one_file)

# 将python中的字典类型转化为json格式的数据存放在文件
# dumps 将字典转化为json的字符串 dump 是转化为json格式数据然后存在文件
one_dict = {'name': '阿登', 'age': '18', 'hobby': None, 10: True}

with open("two_json_file.txt", mode="w", encoding="utf8") as two_file:
    json.dump(one_dict, two_file, ensure_ascii=False, indent=2)  # indent 缩进
    # ensure_ascii=False 中文的不会转化为编码   True 中文会转化为编码
two_dict = [{'status': 1, 'code': '10001', 'data': None, 'msg': '登录成功'},
            {'status': 2, 'code': '10001', 'data': None, 'msg': '登录成功'},
            {'status': 3, 'code': '10001', 'data': None, 'msg': '登录成功'}
            ]
with open("there_json_file.txt", mode="w", encoding="utf8") as there_file:
    json.dump(two_dict, there_file, ensure_ascii=False, indent=2)
    
a = "\u767b\u5f55\u6210\u529f".encode()
print(a.decode()) # 登录成功

pick

image.png image.png
import pickle

dict_1 = {"name": "阿登", 'age': 18}

# dumps转化为bytes类型的字符串
b_str = pickle.dumps(dict_1)
print(b_str)
# 结果:b'\x80\x04\x95\98\xbf\xe7\x99\xbb\x94\x8c\x03age\x94K\x12u.'

# loads 反序列化
str1 = pickle.loads(b_str)
print(str1)  # {'name': '阿登', 'age': 18}

# 对文件的写入 dump
with open("pickle_01.tex", "wb") as f1:
    pickle.dump(dict_1, f1, protocol=2, fix_imports=False)


# 对文件的读取 load
with open("pickle_01.tex", "rb") as f2:
    str2 = pickle.load(f2)
    print(str2)

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)

猴子补丁

一.什么是猴子补丁?

属性在运行时的动态替换,叫做猴子补丁(Monkey Patch)。
猴子补丁的核心就是用自己的代码替换所用模块的源代码,详细地如下
  1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
  2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。

二. 猴子补丁的功能(一切皆对象)

1.拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)


class Monkey:
    def hello(self):
        print('hello')

    def world(self):
        print('world')


def other_func():
    print("from other_func")



monkey = Monkey()
monkey.hello = monkey.world
monkey.hello()
monkey.world = other_func
monkey.world()

三.monkey patch的应用场景

如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高,
但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能
会想到这么做
import ujson as json,但是这么做的需要每个文件都重新导入一下,维护成本依然很高
此时我们就可以用到猴子补丁了
只需要在入口处加上
, 只需要在入口加上:

import json
import ujson  # 需要pip38 install ujson。usjon的dumps和loads比json的快

def monkey_patch_json():
    json.__name__ = 'ujson'
    json.dumps = ujson.dumps
    json.loads = ujson.loads

monkey_patch_json() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果

#其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey
Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey
Patch带了便利的同时也有搞乱源代码的风险!
上一篇 下一篇

猜你喜欢

热点阅读