• json与pickle模块


    序列化与反序列化

    序列化指的是把内存的数据类型转换成一个特定格式的内容,该格式的内容可用于存储或者传输给其他平台使用。

    • 内存中的数据--->序列化--->特定的格式的字符串或bytes类型。
    • 特定的格式字符串或bytes类型--->反序列化--->内存中的数据。

    序列化的用途

    序列化得到的特定格式内容有两种用途

    • 1.可用于存储。
    • 2.传输给其他平台使用 => 跨平台数据交互。

    针对用途1的格式:

    • 可以是一种专用的格式,只有Python可以识别 => pickle 格式

    针对用途2的格式:

    • 应该是一种通用、能够被所用语言识别的格式 => json 格式

    json模块

    • json.dumps():序列化
    import json
    res = json.dumps([1,'abc',True])
    print(res,type(res))
    
    [1, "abc", true] <class 'str'> 单引号变双引号
    
    # 将序列化的内容写入文件
    with open('test.txt',mode='wt',encoding='utf-8') as f:
        res = json.dumps([1,'abc',True])
        f.write(res)
    
    • json.loads():反序列化
    li = json.loads(res)
    print(li,type(li))
    [1, 'abc', True] <class 'list'>
    # 双引号会变为单引号
    
    # 将写入文件的内容读出并反序列化
    with open('test.txt',mode='r',encoding='utf-8') as f:
        res1 = json.loads(f.read())
        print(res1,type(res1))
    
    [1, 'abc', True] <class 'list'>
    

    注意:在python解释器2.7与3.6之后都可以json.loads(bytes类型),但唯独3.5不可以。

    >>> import json
    >>> json.loads(b'{"a":111}')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/linhaifeng/anaconda3/lib/python3.5/json/__init__.py", line 312, in loads
        s.__class__.__name__))
    TypeError: the JSON object must be str, not 'bytes'
    

    json.dump(date,file_obj):将传进去的date序列化为JSON格式后写入文件对象file_obj。

    >>> import json
    >>> with open('a.txt',mode='wt',encoding='utf-8') as f:
    ...     json.dump([True,None,"abc"],f)
    
    [true, null, "abc"]
    

    json.load(file_obj):读取文件内容将其反序列化,返回反序列化后的内容。

    >>> with open('a.txt',mode='rt',encoding='utf-8') as f:
    ...     res = json.load(f)
    ...
    >>> res
    [True, None, 'abc']
    

    json格式序列化后与原数据类型的区别:

    原数据格式 JSON
    True true
    False false
    None null
    'abc' "abc"

    JSON序列化默认支持的对象和类型:

    Python JSON
    dict object
    list, tuple array
    str string
    int, float, int 和 float 派生的枚举 number
    True true
    False false
    None null

    反序列化支持的对象和类型:

    JSON Python
    object dict
    array list
    string str
    number (int) int
    number (real) float
    true True
    false False
    null None

    pickle模块:

    模块 pickle 实现了对一个 Python 对象结构的二进制序列化和反序列化。

    pickle 模块并不安全。你只应该对你信任的数据进行unpickle操作,构建恶意的 pickle 数据来在解封时执行任意代码是可能的。绝对不要对不信任来源的数据和可能被篡改过的数据进行解封。考虑使用 hmac 来对数据进行签名,确保数据没有被篡改。

    pickle.dumps():序列化。

    import pickle
    
    res = pickle.dumps({1,2,3,4,5,'a'}
    print(res,type(res))
    # b'x80x04x95x13x00x00x00x00x00x00x00x8fx94(Kx01Kx02Kx03Kx04Kx05x8cx01ax94x90.' <class 'bytes'>
    

    pickle.loads():反序列化。

    res1 = pickle.loads(res)
    print(res1,type(res1))
    # {1, 2, 3, 4, 5, 'a'} <class 'set'>
    

    pickle.dump(obj,file):将对象 obj 封存以后的对象写入已打开的file文件对象。

    with open('a.txt',mode='wb') as f:
        pickle.dump({'k1':None,"k2":'abc'},f)
    

    pickle.load(f):从已打开的文件 中读取封存后的对象,重建其中特定对象的层次结构并返回。

    with open('a.txt',mode='rb') as f:
        res = pickle.load(f)
        print(res)
        
    {'k1': None, 'k2': 'abc'}
    

    注意:pickle序列化后的内容为bytes类型,所以打开文件必须要为b模式。

    • 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)
    
    • Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

    json与pickle区别

    • JSON 是一个文本序列化格式(它输出 unicode 文本,尽管在大多数时候它会接着以 utf-8 编码),而 pickle 是一个二进制序列化格式;
    • JSON 是可以直观阅读的,而 pickle 不是;
    • JSON是可互操作的,在Python系统之外广泛使用,而pickle则是Python专用的;
    • 默认情况下,JSON 只能表示 Python 内置类型的子集,不能表示自定义的类;但 pickle 可以表示大量的 Python 数据类型(可以合理使用 Python 的对象内省功能自动地表示大多数类型,复杂情况可以通过实现 specific object APIs 来解决)。
    • 不像pickle,对一个不信任的JSON进行反序列化的操作本身不会造成任意代码执行漏洞。

    参考文档:

    https://docs.python.org/zh-cn/3/library/json.html?highlight=json#module-json

  • 相关阅读:
    服务器扫描工具
    Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:443
    [warn] _default_ VirtualHost overlap on port 443, the first has precedence
    Apache环境下配置多个站点的SSL证书
    Linux漏洞扫描工具
    详细解读html中的Map,area标签
    Linux操作系统加固
    MySQL服务安全加固
    redis cluster管理工具redis-trib.rb详解
    Java中使用Jedis操作Redis
  • 原文地址:https://www.cnblogs.com/ChiRou/p/14135832.html
Copyright © 2020-2023  润新知