美文网首页
json|pickle|猴子补丁

json|pickle|猴子补丁

作者: 阿登20 | 来源:发表于2020-09-09 18:46 被阅读0次

    json

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

    image.png

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

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

    image.png image.png
    • json格式的字符串必须是双引号

      json_1 = "{'name':'阿登'}" 不是json格式的数据,因为不能用loads方法,否则会报错
      
    • json 支持的数据类型 str ,int ,tuple , list , dict ,可跨语言,集合就不行。

    #!/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带了便利的同时也有搞乱源代码的风险!
    

    相关文章

      网友评论

          本文标题:json|pickle|猴子补丁

          本文链接:https://www.haomeiwen.com/subject/gbhyektx.html