zoukankan      html  css  js  c++  java
  • python--json和pickle序列化

    字符串存储

    一般需要有信息需要记录的都写到文件上面,把要记录的信息转成字符串,然后在写入到文件中。这算是一种记录方式。

    比如有一组用户信息需要存起来。数据定义好之后就可以写文件。

    info = {
        'name' : 'alex',
        'age':22
    }
    
    with open('test.txt','w')as f:
        f.write(str(info))
    

     test.txt

    {'name': 'alex', 'age': 22} # 这里当作字符串写进来了
    

    读取信息就需要读文件了。

    with open('test.txt','r',encoding='utf-8') as f:
        data = eval(f.readline())
    
    print(data['name']) #alex
    

     这种是要手动转下字符串,Python内置模块中还有一种序列化的方式。

    json模块

    json模块提供了数据序列化和反序列化的功能。

    先看下序列化之后的数据是什么格式的:

    import json
    info = {
        'name' : 'alex',
        'age':22
    }
    
    print(type(json.dumps(info)),[json.dumps(info)])#<class 'str'> ['{"name": "alex", "age": 22}']
    

     可以看出来,序列化之后的数据是字符串类型的(放列表里面更容易看出来)。

    既然是字符串,那么就可以写到文件里面。

    写文件

    import json #json模块
    info = {
        'name' : 'alex',
        'age':22
    }
    
    with open('test.txt','w')as f:
        f.write(json.dumps(info)) #序列化并写入文件
    

    读文件

    import json #加载json模块
    with open('test.txt','r',encoding='utf-8') as f:
        data = json.loads(f.read()) #读文件并反序列化
    
    print(data['name']) #alex
    

     跟上面手动转字符串格式的效果一样,但是这种方法比上面上面那种更好。而且json的数据格式在很多语言中都通用。

    虽然json比较通用,但是只能传递一些简单的数据。如果需要处理一些复杂的数据还有一个模块可以使用。

    pickle模块

    功能和json一样,也是可以序列化和反序列化数据的,但是pickle可以处理一些复杂的数据。

    不同的地方是 pickle序列化之后的数据是二进制格式的。

    import pickle
    
    info = {
        'name' : 'alex',
        'age':22
    }
    
    print(type(pickle.dumps(info)),[pickle.dumps(info)])#<class 'bytes'> [b'x80x03}qx00(Xx04x00x00x00nameqx01Xx04x00x00x00alexqx02Xx03x00x00x00ageqx03Kx16u.']
    

     还用之前的例子处理一次。

    写文件

    import pickle
    info = {
        'name' : 'alex',
        'age':22
    }
    
    with open('test.txt','wb')as f: #因为是二进制,所以是wb
        f.write(pickle.dumps(info)) #和json一样的方法
    

     读文件

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

     pickle不仅可以序列化简单的数据结构,包括复杂的,比如函数、类等。

    比如在上面的数据中加入一个函数。

    写文件

    import pickle
    def fun1(name):     #这里定义了一个函数,并且把函数作为一个value,这里传递过去的应该是一个空间地址。
        print('hello ',name)
    
    info = {
        'name' : 'alex',
        'age':22,
        'fun':fun1
    }
    
    with open('test.txt','wb')as f:
        f.write(pickle.dumps(info))
    

     读文件

    还是用之前的方式读

    import pickle
    with open('test.txt','rb') as f:
        data = pickle.loads(f.read())
    print(data) #AttributeError: Can't get attribute 'fun1' on <module '__main__' from 'E:/pywww/day03/04.py'>
    

     但是这里却给我报了一个错误。

    把之前的函数拿过来。

    import pickle
    def fun1(name):
        print('hello ',name)
    with open('test.txt','rb') as f:
        data = pickle.loads(f.read())
    print(data)  #{'name': 'alex', 'fun': <function fun1 at 0x00000000010F0048>, 'age': 22}
    print(data['fun']('alex')) #hello  alex #None
    

     这里并没有报错,而且函数还可以使用。 那这个函数的内容能不能被修改呢?

    import pickle
    def fun1(name):
        print('hello2222 ',name) #这里打印的内容做了修改
    with open('test.txt','rb') as f:
        data = pickle.loads(f.read())
    print(data['fun']('alex')) #hello2222  alex #None
    

     依然是可以的,两个程序中的内存地址是不可能一样的,那么序列化的内容就不是内存地址,而是整个数据对象。

    另外,pickle中还有两个方法可以实现以上效果。dump和load,这两个方法与dumps和loads的区别就是把文件内容、文件句柄作为参数,可以不用写f.write()和f.read().

    dump写文件

    import pickle
    def fun1(name):
        print('hello ',name)
    
    info = {
        'name' : 'alex',
        'age':22,
        'fun':fun1
    }
    
    with open('test.txt','wb')as f:
        pickle.dump(info,f)   #文件内容、句柄作为参数
    

     load读文件

    import pickle
    def fun1(name):
        print('hello2222 ',name)
    with open('test.txt','rb') as f:
        data = pickle.load(f) #句柄作为参数
    print(data['fun']('alex')) #hello2222  alex #None
    

     效果是一样的。

  • 相关阅读:
    【css】用纯 CSS 判断鼠标进入的方向
    【window】系统禁止运行脚本
    【go】VSCode配置Go插件和debug设置
    【PHP】php之Trait详解
    【layui】laydata 自定义日期之外格式的处理办法
    【PHP】防止视频资源被下载的解决办法
    【Markdown】 编辑器Editor.md集成使用
    代码之间为什么要加空格?
    求求你,别问了,Java字符串是不可变的
    养生吧,程序员!
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7273638.html
Copyright © 2011-2022 走看看