zoukankan      html  css  js  c++  java
  • Python 序列化模块(json,pickle,shelve)

    json模块

    JSON (JavaScript Object Notation):是一个轻量级的数据交换格式模块,受javascript对象文本语法启发,但不属于JavaScript的子集。

    常用方法:

    dump(obj,fp):将对象以字符串的形式写入文件中。

    load(fp):将数据从文件中读出,并返回(需要变量接收)数据的原类型。

    dumps(obj):将对象转换成json字符串形式。

    loads(str):将json字符串数据转换成原来的数据类型。

    实例如下:dumps(obj) | loads(str)

    import json
    
    dict_1 = {"电影":"黄飞鸿","电视剧":"霍元甲"}
    
    json_str = json.dumps(dict_1)  # 将字典转换成json的字符串类型
    
    dict_2 = json.loads(json_str)  # 将json的字符串类型转换成原数据
    
    print(json_str,type(json_str))
    
    print(dict_2.items(),type(dict_2))
    
    # 打印内容如下
    {"u7535u5f71": "u9ec4u98deu9e3f", "u7535u89c6u5267": "u970du5143u7532"} <class 'str'>
    dict_items([('电影', '黄飞鸿'), ('电视剧', '霍元甲')]) <class 'dict'>

    实例如下:dump(obj,fp) | load(fp)

    import json
    # 向文件中写入json数据
    
    dict_1 = {"电影":"黄飞鸿","电视剧":"霍元甲"}
    
    file_write = open("json.txt",mode="w",encoding="utf-8")
    
    json.dump(dict_1,file_write)  # 将字典以json的字符串类型写入文件
    
    file_write.close()
    # 从文件中读取json数据
    
    file_read = open("json.txt",mode="r",encoding="utf-8")
    
    dict_2 = json.load(file_read) # 将文件中内容转换成原数据类型并返回
    
    file_read.close()
    
    print(dict_2.items(),type(dict_2)) # 打印转换后的数据
    
    # 打印内容如下
    dict_items([('电影', '黄飞鸿'), ('电视剧', '霍元甲')]) <class 'dict'>

    这里需要注意的是json模块dump(obj,fp)虽然可以多次上传,但是在load时会报错,load(fp)函数不能转换多次dump的数据。所以如果想要向json文件中新增数据时,需要将数据load下来转换成原数据,然后在原数据基础上进行新增。最后将处理后的数据dump覆盖写到文件中。

    pickle模块:

    属于python专有的模块,用法,功能与json类似。

    常用方法:

    dump(obj,fp):将对象以字符串的形式写入文件中。

    load(fp):将数据从文件中读出,并返回(需要变量接收)。

    dumps(obj):将对象转换成json字符串形式。

    loads(str):将json字符串数据转换成原来的数据类型。

    dump(obj,fp)  |  load(fp) 示例如下;

    import pickle
    # 将数据以json方式写入文件
    
    dict_1 = {"电影":"黄飞鸿","电视剧":"霍元甲"}
    
    file_write = open("pickle.txt",mode="wb")
    
    pickle.dump(dict_1,file_write)  # 将字典以字节的形式写入文件
    
    file_write.close()
    # 从文件中以json方式读取数据
    
    file_read = open("pickle.txt",mode="rb")
    
    dict_2 = pickle.load(file_read)  # 将文件中内容转换成原数据类型并返回
    
    file_read.close()
    
    print(dict_2.items(),type(dict_2)) # 打印转换后的数据
    
    # 打印内容如下
    dict_items([('电影', '黄飞鸿'), ('电视剧', '霍元甲')]) <class 'dict'>

    dumps(obj)  |  loads(obj) 示例如下;

    import pickle
    
    dict_1 = {"电影":"黄飞鸿"}
    
    pickle_byte = pickle.dumps(dict_1)  # 将字典转换成pickle字节
    
    print(pickle_byte)
    
    # 将pickle字节转换成原数据
    
    dict_2 = pickle.loads(pickle_byte)
    
    print(dict_2.items(),type(dict_2)) # 打印转换后的数据
    # 打印内容如下
    b'x80x03}qx00Xx06x00x00x00xe7x94xb5xe5xbdxb1qx01X	x00x00x00xe9xbbx84xe9xa3x9exe9xb8xbfqx02s.'
    dict_items([('电影', '黄飞鸿')]) <class 'dict'>

    与json不同的是pickle可以多次dump多次load,如下:

    import pickle
    
    dict_1 = {"电影":"黄飞鸿"}
    
    dict_3 = {"电视剧":"霍元甲"}
    
    dict_5 = {"动画片":"葫芦娃"}
    
    file_write = open("pickle.txt",mode="wb")
    
    pickle.dump(dict_1,file_write)  # 将dict_1以字节的形式写入文件
    
    pickle.dump(dict_3,file_write)  # 将dict_3以字节的形式写入文件
    
    pickle.dump(dict_5,file_write)  # 将dict_5以字节的形式写入文件
    
    file_write.close()
    
    file_read = open("pickle.txt",mode="rb")
    
    dict_2 = pickle.load(file_read)  # 将文件中内容转换成原数据类型并返回
    
    dict_4 = pickle.load(file_read)  # 将文件中内容转换成原数据类型并返回
    
    dict_6 = pickle.load(file_read)  # 将文件中内容转换成原数据类型并返回
    
    file_read.close()
    
    print(dict_2.items(),type(dict_2)) # 打印转换后的数据
    
    print(dict_4.items(),type(dict_4)) # 打印转换后的数据
    
    print(dict_6.items(),type(dict_4)) # 打印转换后的数据
    # 打印内容如下
    dict_items([('电影', '黄飞鸿')]) <class 'dict'>
    dict_items([('电视剧', '霍元甲')]) <class 'dict'>
    dict_items([('动画片', '葫芦娃')]) <class 'dict'>

    小结:

    1、json属于通用的模块,Java,JS等其它语言也支持。

         pickle是Python私有的,只支持Python。

    2、json将对象转换成json字符串类型。

         pickle将对象转换成pickle字节类型。

    3、json只能转换dict,list,tuple,str,int,float,bool值等简单数据类型

         pickle能转换除了lamda以外的所有已知数据类型。

    4、json虽然可以多次dump但是load会报错(这是最大的伤)。

         pickle可以多次dump,多次load。

    shelve模块

    使用json或者pickle持久化数据,能dump多次,但load的话只能取到最新的dump, 因为先前的数据已经被后面dump的数据覆盖掉了。如果想要实现dump多次不被覆盖,就可以想到使用shelve模块。shelve模块可以持久化所有pickle所支持的数据类型。另外,写程序的时候如果不想用关系数据库那种重量级的去存储数据,也可以用到shelve。

    shelve是用key来访问的,使用起来和字典类似。 要注意的是,在shelve模块中,key必须为字符串,而值可以是python所支持的数据类型。

    另外,shelve其实用anydbm去创建DB并且管理持久化对象的。

    shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。 可以像字典一样使用get来获取数据等。

    如下操作:

    import shelve
    
    f_shelve = shelve.open('shelve') # 创建一个文件句柄
    
    f_shelve["name"] = "小明" # 向文件中存放数据
    
    f_shelve["age"] = 21 # 向文件中存放数据
    
    f_shelve["sex"] = ""

    运行后会生成3个文件:shelve.bak shelve.dat shelve.dir,如下:

    shelve.dat 存储的就是b字节数据类型的数据。bak和dir后缀从字面上看是备份和目录,具体做什么的不是很清楚。

    当我们写好数据后,如何读取呢?

    import shelve
    
    f_shelve = shelve.open('shelve') # 创建一个文件句柄
    
    # 打印文件内容,和类型
    
    print(f_shelve["name"],f_shelve["age"],f_shelve["sex"],type(f_shelve))
    
    # 打印内容如下
    小明 21 男 <class 'shelve.DbfilenameShelf'>

    既然f_shelve类似于字典,那我们也可以使用for循环进行打印,如下:

    import shelve
    
    f_shelve = shelve.open('shelve') # 创建一个文件句柄
    
    # 使用for循环打印内容
    
    for k,v in f_shelve.items():
    
        print(k,v)
    
    # 打印内容如下
    name 小明
    age 21
    sex 男

    f_shelve现在是一个特殊的文件句柄,它可以执行字典的多数方法,对文件里的数据进行操作。

    import shelve
    
    f_shelve = shelve.open('shelve') # 创建一个文件句柄
    
    f_shelve["list"] = [1,2,3]  # 向文件中添加数据列表
    
    f_shelve["list"].append("abc") # 向列表中追加内容.
    
    f_shelve["list"].pop(1) # 从列表中删除一个元素
    
    
    
    f_shelve["name"] = "小明" # 向文件中追加内容
    
    f_shelve["name"] = "小红" # 修改name所对应的值
    
    print(f_shelve["list"],f_shelve["name"],sep="
    ")
    
    # 打印内容如下
    [1, 2, 3]
    小红

    通过上面的打印内容我们可以发现,我们将列表写入文件后,然后在读取出来进行追加和删除元素,并没有对文件产生影响,文件中的列表内容还是原来的值。而我们向文件中添加字符串时,在读取出来对字符串进行修改发现数据被修改了。

    由此我们可以知道在向文件中写入一个可变的数据时,如果读取出来对数据进行修改只是在内存中的修改,修改后的数据并没有被真正写入到文件中。那么我们该如何进行操作呢?这时就需要回写了。

    import shelve
    
    # 创建一个特殊的文件句柄,并添加回写功能
    
    f_shelve = shelve.open('shelve',writeback=True)  # 启用会写
    
    f_shelve["list"] = [1,2,3]  # 向文件中添加数据列表
    
    f_shelve["list"].append("abc") # 向列表中追加内容.
    
    f_shelve["list"].pop(1) # 从列表中删除一个元素
    
    print(f_shelve["list"])
    
    # 打印内容如下
    [1, 3, 'abc']

    这回我们在修改列表时,可以看出列表的数据确实被修改了。

    总结如下:

    1、shelve模块将内存数据以字典的类型(key,value)通过文件持久化,模拟出简单的db效果。

    2、shelve模块可以持久化任何pickle所支持的python数据格式,但是它的key必需得是字符串。

    3、shelve可以看作是pickle模块的一个封装,但它实现了可以多次dump(后面的dump不会覆盖前面的)和多次load。

    4、shelve访问己有key时,实际上取出的是数据源给出的一份拷贝,所以对于拷贝做出的增加和删除等操作都需要用writeback=True参数才能实现写入回文件中进行修改。

    5、shelve对于d[key] = data这种操作,视为存储数据,无则新增,有则覆盖,对与访问key当中的值(条目)进行修改,默认不回写并不矛盾和冲突。

     


     

     

    下一篇:模块os,sys,hashlib,collections的简单介绍:https://www.cnblogs.com/caesar-id/p/10427386.html

     

  • 相关阅读:
    快手视频下载脚本
    ffmpeg 加载双语字幕
    GNU Wget 1.19.1 static built on mingw32
    Struts配置应用2
    Struts配置应用1
    spring-IOC控制反转
    spring-纯pojo切面
    spring面向切面编程的方式实现
    spring-CGLib动态代理
    spring-JDK_AOP动态代理
  • 原文地址:https://www.cnblogs.com/caesar-id/p/10415132.html
Copyright © 2011-2022 走看看