zoukankan      html  css  js  c++  java
  • 序列化模块

    什么叫序列化——

    将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化

    什么叫反序列化-——

    将序列化后的内容转换回来的过程就叫做 反序列化

    为什么要序列化——

    1,以某种存储形式使自定义对象持久化

    2,将对象从一个地方传递到另一个地方

    3,使程序更具维护性

    序列化的最终目的就是为了保存下来(比如以文件形式存在硬盘上),或者是发送出去(比如通过网络发送一个类到服务器上),但是文件是没有字典这个概念的,所以我们只能将字典转化成字符串放到文件中。

    为什么反序列化不使用eval()——

    eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。
    BUT!强大的函数有代价。安全性是其最大的缺点。
    想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。 而使用eval就要担这个风险。

    json模块

    所有语言都通用,他能序列化的数据是有限的:

    序列化中的内容只能包含:字典 列表 数字 字符串,如果是元祖——自动转成列表的样子

    json模块提供了四个功能:dumps,dump,loads,load

    #dumps()和loads()
    
    ret = json.dumps({"k1":"k2"})#序列化,将字典变成了字符串
    print(repr(ret),type(ret))#'{"k1": "k2"}' <class 'str'>
    ret2 = json.dumps((1,2,3))#'[1, 2, 3]' <class 'str'>
    print(repr(ret2),type(ret2))
    
    ret2=json.loads(ret)#反序列化,将字符串格式的字典转换为数据结构,字符串只能包含一个数据结构,但是这个数据结构可以嵌套
    print(repr(ret2),type(ret2))#{'k1': 'k2'} <class 'dict'>
    
    
    #dump()和load()
    
    #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
    # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
    f = open("json_1","w")
    dic={"k1":"k2"}
    json.dump(dic,f) #  这么写进去是没有办法换行的,再使用load()反序列化时,就会报错
    json.dump((1,2,3,4,5),f)
    f.close()
    
    f = open("json_1")
    dic2=json.load(f)#把文件中的内容转换成数据结构返回
    f.close()
    print(dic2)
    
    #当文件中每一行都是一个数据结构时,可以读取其中的每一行
    f=open("json_1","r")
    for i in f:
        print(json.loads(i))
    f.close()
    #
    f1=open("json_1","w")
    str = json.dumps({"k2":"v2"})
    f1.write(str+"
    ")#追加时注意换行符的位置,要判断换行符在前还是在后
    f1.close()

    json的dumps()

    json.dumps()会将回将内部字符装换成编码,将ensure_ascii参数设置为False就能变回原字符

    >>> import json
    >>> json.dumps("魏文刚")
    '"\u9b4f\u6587\u521a"'
    >>> json.dumps("魏文刚",ensure_ascii=False)
    '"魏文刚"'

    自定义序列化规则

    import datetime
    import json
    
    dic = {
        'k1':123,
        'ctime':datetime.datetime.now()
    }
    
    class MyEncoder(json.JSONEncoder):
        def default(self, o): # o是数据类型
            if isinstance(o,datetime.datetime):
                return o.strftime('%Y-%m-%d')
            else:
                return super(MyEncoder,self).default(o)
    
    v = json.dumps(dic,cls=MyEncoder)
    print(v)
    # {"k1": 123, "ctime": "2018-05-15"}

    pickle模块

    pickle是python特有的,能够序列化任何数据类型(包括对象),python专有的不能和其他语言兼容,结果是bytes

    方法和json一样,dumps,loads,dump,load

    读写文件时,要用b模式

    import pickle
    ret = pickle.dumps({"k":"v"})
    print(ret)
    
    #b'x80x03}qx00Xx01x00x00x00kqx01Xx01x00x00x00vqx02s.'
    #用pickle序列化的类型,反序列化也必须用pickle

    pickle模块再向文件中写时不用换行,读的时候每次读一个数据类型

    import pickle
    f = open("a","wb")
    dict = {"用户名":178973,"用户名2":21324325}
    pickle.dump(dict,f)
    pickle.dump([1,2,3,4,5,6],f)
    f.close()
    f = open("a","rb")
    print(pickle.load(f))
    print(pickle.load(f))
    #{'用户名': 178973, '用户名2': 21324325}
    #[1, 2, 3, 4, 5, 6]

    shelve模块

    只限于python语言,能转换所有的数据类型,只有一种使用方法,使用方法类似于字典

    shelve 只提供一个open,shelve.open('文件名')拿到一个文件句柄,这个文件句柄就可以当做字典操作
    正常情况下shelve打开的文件句柄感知不到值的修改,设置writeback = True就可以保存修改内容了

    flag参数

    flag=c  默认参数,打开文件进行读写,必要时创建该文件

    flag=w  打开文件进行读写,如果文件不存在,不会创建他

    flag=n  打开文件进行读写,但总创建一个新的空白文件

    import shelve
    f = shelve.open('shelve_file')
    f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'}  #直接对文件句柄操作,就可以存入数据
    f.close()
    
    import shelve
    f1 = shelve.open('shelve_file')
    existing = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
    f1.close()
    print(existing)
    #结果
    #{'int': 10, 'float': 9.5, 'string': 'Sample data'}

    修改

    f=shelve.open("222")
    print(f["q"])
    f["q"].append("c")
    print(f["q"])
    f.close()
    #
    f=shelve.open("222",writeback=True)
    print(f["q"])
    f["q"].append("a")
    print(f["q"])
    f.close()
    #运行结果
    #[1, 2, 3, 4, 5]
    #[1, 2, 3, 4, 5]
    #[1, 2, 3, 4, 5]
    #[1, 2, 3, 4, 5, 'a']
    
  • 相关阅读:
    Git centos 6.5 搭建(gitosis)
    error at ::0 can't find referenced pointcut xxx
    MySql 主从配置
    svn 搭建
    Flatbuffers学习
    python3 获取函数变量
    pyqt5 重启相同线程错误:QThread: Destroyed while thread is still running
    WIN10 使用注册表设置单应用KIOSK模式(不限win10版本)
    WIN10 使用POWERSHELL 设置单应用KIOSK模式(win10家庭版或企业版)
    py文件加密打包成exe文件
  • 原文地址:https://www.cnblogs.com/wwg945/p/7840451.html
Copyright © 2011-2022 走看看