zoukankan      html  css  js  c++  java
  • python常用模块之json、pickle模块

    python常用模块之json、pickle模块

    什么是序列化?

    序列化就是把内存里的数据类型转换成字符,以便其能存储到硬盘或者通过网络进行传输,因为硬盘或网络传输时只接受bytes。

    为什么要序列化?

    举个例子来说,你在上班打游戏,突然你的领导过来了,你就把游戏给关了,然后你的领导走了,你接着打开了这个游戏,此时游戏又从你上次停止的地方继续运行,你的游戏进度肯定保存到了硬盘上,是以何种形式的呢?游戏过程中产生的数据都是不规律的,可能在关游戏的时候就出现了10个嵌套字典,3个列表的数据集合在内存里,需要存下来?你怎么存?把列表变成文件多行多列的形式报错,那么嵌套字典呢?所以,若是有某种办法可以直接把内存数据存到硬盘上,下次程序再启动,再从硬盘里读到内存里,还是原来的格式的话,那就是极好的。

    用于序列化的两个模块

    • json:用于字符串和python数据类型之间的转换
    • pickle:用于python特有的类型和python数据类型之间的转换

    我们先假设下有这么个数据:

    data = {
        "roles":[
            {'role':"monster","type":"pig","life":50},
            {'role':"hero","type":"关羽","life":80}
        ]
    }
    

    我们想把这个数据保存到文件里,改如何操作呢?

    f = open("序列化.txt",'w',encoding='utf-8')
    f.write(str(data))  # 以字符串类型写进文件中
    f.close()
    

    等等,刚刚不是还在说嵌套字典如何写进文件嘛,那现在已经写进去了本章结束 ,不可能的,因为你要怎么读取呢?

    f = open("序列化.txt",'r',encoding='utf-8')
    d = f.read()
    print(d['roles'])
    f.close()
    

    这样写会立马报错,因为d此时是str类型,那么我们应该怎么办呢?

    f = open("序列化.txt",'r',encoding='utf-8')
    d = f.read()
    d = eval(d)  # 使用eval可以把字符类型转换为任意类型
    print(d['roles'])  # 成功了
    

    此时我们可以引出:

    • 把内存数据转换成字符,叫序列化
    • 把字符串转换为内存数据,叫反序列化

    json模块

    json模块提供了4个功能:dump、dumps、load、loads,其中:dump和dumps叫序列化,load和loads叫做反序列化。
    1.json.dumps():把内存数据变成字符串

    import json
    
    data = {
        "roles":[
            {'role':"monster","type":"pig","life":50},
            {'role':"hero","type":"关羽","life":80}
        ]
    }
    
    d = json.dumps(data)
    print(type(d))  # <class 'str'>
    print(d)  # {"roles": [{"role": "monster", "type": "pig", "life": 50}, {"role": "hero", "type": "u5173u7fbd", "life": 80}]}
    

    2.json.dump():不仅把内存数据变成字符串,还把它存到文件里

    import json
    
    data = {
        "roles":[
            {'role':"monster","type":"pig","life":50},
            {'role':"hero","type":"关羽","life":80}
        ]
    }
    
    f = open('test.json','w')  # 首先要打开这个文件,注意:序列化后的文件都是以.json结尾
    json.dump(data,f)  # 把内存数据序列化到文件中
    

    3.json.loads():把字符串转换成内存数据

    import json
    
    data = {
        "roles":[
            {'role':"monster","type":"pig","life":50},
            {'role':"hero","type":"关羽","life":80}
        ]
    }
    
    d = json.dumps(data)
    d2 = json.loads(d)  # 应把data数据注释后运行
    print(d2)  # {'roles': [{'role': 'monster', 'type': 'pig', 'life': 50}, {'role': 'hero', 'type': '关羽', 'life': 80}]}
    

    4.json.load():把字符串从文件中读取,然后转成内存数据

    import json
    
    f = open("test.json",'r')
    data = json.load(f)
    print(data)  # 同样也可以拿到文件
    

    那么此时有一个大疑问,就把内存数据转换成字符串,也不给存放起来,用这个有什么意义?
    作用1:把你的内存数据通过网络共享给其他人
    作用2:定义了不同语言的交互规则

    我们可以使用文本文档、xml、json保存数据,那么它们的区别数是什么?
    1.文本文档,缺点:不能共享复杂的数据
    2.xml,缺点:占用内存大
    3.json,优点:占用空间小,可读性非常好

    那么我们可以dump多次和load多次吗?

    # dump多次,是可以成功的
    import json
    
    d = {'name':'alex','age':22}
    l = [1,2,3,4,"rain  "]
    
    f = open("test.json",'w')
    json.dump(d,f)
    json.dump(l,f)
    f.close()
    
    # load多次,不能成功
    import json
    
    f = open("test.json",'r')
    d1 = json.load(f)
    d2 = json.load(f)  # 因为数据是连在一起的,所以没法load多次,即立马报错,raise JSONDecodeError("Extra data", s, end)
    f.close()
    

    json本身的设计就是dump一次,load一次的

    pickle模块

    1.pickle.dumps():将内存数据转换成字符

    import pickle
    d = {'name':'alex','age':22}
    
    s = pickle.dumps(d)
    print(s)  # b'x80x03}qx00(Xx04x00x00x00nameqx01Xx04x00x00x00alexqx02Xx03x00x00x00ageqx03Kx16u.'  # 直接就是bytes类型
    

    2.pickle.loads():将字符转换成为内存数据

    import pickle
    d = {'name':'alex','age':22}
    
    s1 = pickle.dumps(d)
    
    s2 = pickle.loads(s1)
    print(s2)  # {'name': 'alex', 'age': 22}
    

    3.pickle.dump():把内存数据转换成字符,并存到文件中

    import pickle
    d = {'name':'alex','age':22}
    
    f = open("test.pkl","wb")
    pickle.dump(d,f)
    f.close()
    
    此时文件中就生成pickle自己的格式:€}q (X   nameqX   alexqX   ageqKu.
    

    4.pickle.load():把文件中内容读取出来然后转换成内存数据

    import pickle
    
    f = open("test.pkl","rb")
    d = pickle.load(f)
    print(d)  # {'name呢': 'alex', 'age': 22}
    f.close()
    

    此时,json和pickle模块都结束了。

    有人会问,既然json和pickle的功能是一样的,那么为什么还要存在两个模块呢?

    1.都不能dump多次
    2.json能做的pickle不能做,pickle能做的json不能做
    例如:
        json支持的数据类型:int,str,tuple,list,dir,可以跨平台
        pickle支持的数据类型:支持python里所有的数据类型
            缺点:只能在python中使用
    
  • 相关阅读:
    FTP与HTTP上传文件的对比
    【FTP】Wireshark学习FTP流程
    【CSS】div
    浏览器URL中“#” “?” &“”作用
    【EF】vs2017中没有EF模型
    C# List的使用
    C# Dictionary使用
    Git/GitHub的一些问题
    PHP中的break与continue
    css使文字垂直水平居中
  • 原文地址:https://www.cnblogs.com/xiaoyafei/p/9036959.html
Copyright © 2011-2022 走看看