python Json与pickle数据序列化

发布时间:2018-02-28 15:58:28编辑:admin阅读(3183)

    在程序运行的过程中,所有的变量都是在内存中。一旦程序结束,变量所占用的内存就被操作系统全部回收。

    为了避免数据丢失,把变量从内存中变成可存储或传输的过程称之为序列化

    序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。


    反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化


    先用常规的方法将一个字典写入到文件中

    info = {
        'name':"zhang",
        'age':22
    }
    with open('test.txt','w') as f:
        #字典无法写入文件,必须转换成字符串
        f.write(str(info))

    执行程序,查看test.txt文件内容如下:

    {'name': 'zhang', 'age': 22}


    读取文件内容,加载到内存中,需要用到eval

    eval() 将字符串str当成有效的表达式来求值并返回计算结果

    with open('test.txt','r') as f:
        data = eval(f.read())
        print(data['name'])

    执行输出 zhang


    下面介绍 标准用法,用json模块

    序列化:

    import json
    info = {
        'name':"zhang",
        'age':22
    }
    with open('test.txt','w') as f:
        f.write(json.dumps(info))
        #查看序列化之后的变量类型
        print(type(json.dumps(info)))

    执行输出 class 'str'

    可以看到类型是字符串了。


    反序列化:

    import json
    with open('test.txt','r') as f:
        data = json.loads(f.read())
        print(data['name'])

    执行输出 zhang


    json只能处理简单的数据类型,比如:字符串、字典、列表等

    不支持函数,类 转换。


    json主要用于不同语言之间数据交互

    是目前主流的数据交互格式。


    那么其他复杂的数据类型,要序列化,怎么办呢?用pickle


    pickle,用于python特有的类型 和 python的数据类型间进行转换。


    pickle的语法和json是一样的

    序列化

    import pickle
    info = {
        'name':"zhang",
        'age':22
    }
    #因为pickle之后,类型是二进制,所以模式是wb
    with open('test.txt','wb') as f:
        f.write(pickle.dumps(info))
        #查看序列化之后的变量类型
        print(type(pickle.dumps(info)))

    执行输出 class 'bytes'


    反序列化

    import pickle
    with open('test.txt','rb') as f:
        data = pickle.loads(f.read())
        print(data['name'])

    执行输出 zhang


    注意:pickle的数据类型只有python能用,其他语言,比如java是不能识别的。


    pickle代码优化

    序列化

    import pickle
    info = {
        'name':"zhang",
        'age':22
    }
    with open('test.txt','wb') as f:
        pickle.dump(info,f)

    执行效果同上

    pickle.dump(info,f) 就等同于 f.write(pickle.dumps(info))


    反序列化

    import pickle
    with open('test.txt','rb') as f:
        data = pickle.load(f)
        print(data['name'])

    执行效果同上

    pickle.load(f) 等同于 pickle.loads(f.read())


    举一个特殊例子

    多次序列化


    这里先序列化一次,修改年龄之后,再序列化一次

    import json
    
    info = {
        'name':"zhang",
        'age':22
    }
    with open('test.txt','w') as f:
        json.dump(info,f)
        info['age'] = 21
        json.dump(info, f)

    执行程序,查看test.txt内容

    {"name": "zhang", "age": 22}{"name": "zhang", "age": 21}


    反序列化

    import json
    with open('test.txt','r') as f:
        data = json.load(f)
        print(data['name'])

    执行程序,报错

    json.decoder.JSONDecodeError: Extra data: line 1 column 29 (char 28)


    注意:在python 3.0版本中,一个文件只允许序列化一次。

    举个场景,VMware Workstation软件可以创建多个快照,并且可以恢复到任意的快照。它是怎么做到的呢?就是每个快照,有独立的文件。

    所以在python中,要想序列化多次,必须每次保存的文件是不一样的才行。




关键字