• 12 python json&pickle&shelve模块


     

     1、什么叫序列化

     序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes(字节)

    2、用于序列化的两个模块,json和pickle

    json,用于字符串 和 python数据类型间进行转换
    pickle,用于python特有的类型 和 python的数据类型间进行转换
    Json模块提供了四个功能:dumps、dump、loads、load
    
    pickle模块提供了四个功能:dumps、dump、loads、load

    2.1json和pickle的对比分析

    json vs pickle:
    
    JSON:
    
    优点:跨语言、体积小
    
    缺点:只能支持intstrlist	upledict
    
    Pickle:
    
    优点:专为python设计,支持python所有的数据类型
    
    缺点:只能在python中使用,存储数据占空间大 
    # 把内存数据转成字符串数据类型,叫序列化  : dumps dump
    # 把字符串数据类型转化成内存数据 叫反序列化 : loads load
    dumps和dump,load和loads的区别:
    
    dumps是将对象序列化,loads将序列化字符串反序列化。
    dump是将对象序列化并保存到文件中,load将序列化字符串从文件读取并反序列化。

    重点:dumps仅转为为字符串,loads反序列化,转化为原型
    # dumps仅转化成字符串
    import json
    data = {'k1':123,'k2':'hello'}
    d = json.dumps(data)
    d1 = json.loads(d)
    print('序列化',d,type(d))
    print('反序列化d1',d1,type(d1))
    输出为:
    序列化 {"k1": 123, "k2": "hello"} <class 'str'>
    反序列化d1 {'k1': 123, 'k2': 'hello'} <class 'dict'>
    重点:dump先主动转化再写入文件,load读取json文件返回原型
    #转化为字符并写入文件dump
    data2 ={'a1':123,'b1':456}
    with open('test序列.py','a+',encoding='utf-8') as f:
        f1 = json.dump(data2,f)
        print('序列化dump:',f1,type(f1))
    序列化dump: None <class 'NoneType'>
    因为:json.dump主要用来json文件读写
    
    #反序列化:
    import json
    with open('test序列.py','r') as f2:
        file = json.load(f2)
        print('反序列化load:',file,type(file))
    反序列化load: {'a1': 123, 'b1': 456} <class 'dict'>
    因为: json.load是读取json数据 
    
    json.dumps : ’dict’转成str   json.dump是将python数据保存成json
    
    json.loads:str转成’dict’          json.load是读取json数据 
    
    json.load是解析json文件的;json.loads是解析json字符串的
    dumps 和loads对应
    dump 和 load 对应
    # 只是把数据转成字符串存到内存里的意义?
    # json.dumps json.loads
    # 1 把你的内存数据通过网络,共享给远程其他人
    # 2 定义了不同语言之间的交互规则
    # (1)纯文本,坏处:不能共享复杂的数据类型。(2)xml,坏处:占空间大。(3)json,简单,可读性好

    3、pickle模块

    与JSON不同的是pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化或者python程序间进行互相传输对象的方法,因此它支持了python所有的数据类型。
    
    import pickle
    data = {'k1':123,'k2':'abc'}
    d = pickle.dumps(data)
    d2 = pickle.loads(d)
    print('序列化',d,type(d))
    print('反序列化d1',d2,type(d2))
    
    输出:
    序列化 b'x80x03}qx00(Xx02x00x00x00k1qx01K{Xx02x00x00x00k2qx02Xx03x00x00x00abcqx03u.' <class 'bytes'>
    pickle.dumps输出为二进制模式,bytes就是单纯的二进制
    
    反序列化d1 {'k1': 123, 'k2': 'abc'} <class 'dict'>
    
    (2)
    pickle.dump/pickle.load
    
     #pickle只能以二进制格式存储数据到文件
    
    f = open('test1.txt','wb')
    data = {'k1':123,'k2':'abc'}
    f1 = pickle.dump(data,f)    #序列化对象到文件
    print('pickle.dump(data,f):',f1,type(f1))
    f = open('test1.txt','rb')
    red = pickle.load(f)   #从文件中反序列化对象
    print('pickle.load(f)',red,type(red))
    
    输出结果:
    pickle.dump(data,f): None <class 'NoneType'>#保存的为对象
    pickle.load(f) {'k1': 123, 'k2': 'abc'} <class 'dict'>

    4、shelve

    Shelve是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的。

    用途:可以作为一个简单的数据存储方案

    shelve与pickle类似用来持久化数据的,不过shelve是以键值对的形式,将内存中的数据通过文件持久化,

    值支持任何pickle支持的python数据格式,它会在目录下生成三个文件。

    import shelve
    
    s = shelve.open('test_shelf.db') #创建shelve并打开
    try:
        s['kk'] = {'int': 10, 'float': 9.5, 'String': 'Sample data'} #写入数据
        s['MM'] = [1, 2, 3]
    finally:
        s.close() #关闭文件
    
    
    import shelve
    s = shelve.open('test_shelf.db') #打开文件
    print(s['kk']) #访问数据
    s.close()
    
    输出:{'int': 10, 'float': 9.5, 'String': 'Sample data'} <class 'dict'>2)对于存储的key,value值,只能添加key,value,可修改整个value,不能单独修改列表或字典中的元素
    
    s = shelve.open('test_shelf.db') #打开文件
    
    #添加数据:s['k2']=[1,2,3] 
    
    若s['k2'] = [1,2,3]
    #添加后修改(NO) s['k2'][0]=99   #修改存储的value的单个值时不生效也不报错
    
    #可以整个修改: s['k2']=(33,44)   #可以修改key的value
    
    写回(write-back)由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
    
    >>> s = shelve.open('test_s.db',writeback=True)  #使用回写功能打开
    >>> print(s['k1'])   #初始值
    {'float': 8.8, 'string': 'python', 'int': 10}
    >>> print(s['k2'])
    (33, 44)
    >>> s['k1']['float']='99.99'  #修改字典中的元素
    >>> print(s['k1'])   #成功修改
    {'float': '99.99', 'string': 'python', 'int': 10}
    # 1.创建一个shelf对象,直接使用open函数即可
    
    import shelve
    s = shelve.open('test_shelf.db')         #
    try:
        s['kk'] = {'int': 10, 'float': 9.5, 'String': 'Sample data'}
        s['MM'] = [1, 2, 3]
    finally:
        s.close()
    
    # 2.如果想要再次访问这个shelf,只需要再次shelve.open()就可以了,然后我们可以像使用字典一样来使用这个shelf
    
    import shelve
    try:
        s = shelve.open('test_shelf.db')
        value = s['kk']
        print(value)
    finally:
        s.close()
    
    # 3.对shelf对象,增、删、改操作
    
    import shelve
    s = shelve.open('test_shelf.db', flag='w', writeback=True)
    try:
        # 增加
        s['QQQ'] = 2333
        # 删除
        del s['MM']
        # 修改
        s['kk'] = {'String': 'day day up'}
    finally:
        s.close()
    
    # 注意:flag设置为‘r’-只读模式,当程序试图去修改一个以只读方式打开的DB时,将会抛一个访问错误的异常。异常的具体类型取决于anydbm这个模块在创建DB时所选用的DB。异常举例:anydbm.error: need ‘c’ or ‘n’ flag to open new db
    
    # 4.循环遍历shelf对象
    
    import shelve
    s = shelve.open('test_shelf.db')
    try:
        # 方法一:
        for item in s.items():
            print ('键[{}] = 值[{}]'.format(item[0], s[item[0]]))
        # 方法二:
        for key, value in s.items():
            print(key, value)
    finally:
        s.close()

    writeback=True,对子字典修改完后要写回,否则不会看到修改后的结果
    open(filename, flag='c', protocol=None, writeback=False):
  • 相关阅读:
    Android编译系统环境过程初始化分析【转】
    Android内核开发:理解和掌握repo工具【转】
    QQ空间如何设置被删除的好友不能访问空间
    用简单的C语言实现多任务轮流切换(模拟操作系统线程机制)【转】
    可重入函数与不可重入函数【转】
    关于链表中头指针和头结点的理解【转】
    C语言中static的使用方法【转】
    指针与地址的区别【转】
    柔性数组【转】
    void及void指针介绍【转】
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9506689.html
Copyright © 2020-2023  润新知