zoukankan      html  css  js  c++  java
  • Python 入门之 内置模块 -- 序列化模块(json模块、pickle模块)

    1、序列化

    序列化的本质就是将一种数据结构(如字典,列表)等转换成一个特殊的序列(字符串或者bytes)的过程就叫做序列化。

    Python中这种序列化模块有三种:

    ​ ①json模块 :

    ​ 不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])

    ​ json序列化只支持部分Python数据结构:dict,list, tuple,str,int, float,True,False,None

    ​ ②pickle模块:

    ​ 只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。

    ​ 支持Python所有的数据类型包括实例化对象。

    ​ ③shelve模块:类似于字典的操作方式去操作特殊的字符串。

    (1)序列化模块就是将一个常见的数据结构转化成一个特殊的序列,并且这个特殊的序列还可以反解回去

    (2)主要用途

    <1> 文件读写数据

    <2> 网络传输数据

    (3)json模块

    <1> json模块是将满足条件的数据结构转化成特殊的字符串,并且也可以反序列化还原回去

    <2> 能够序列的数据类型:dict,list, tuple,str,int, float,True,False,None

    # 4个方法 分为2组
    dumps   loads    # ----  用于网络传输
    dump     load    # ----  用于文件存储
    

    1> dumps、loads

    [1] 将字典类型转换成字符串类型
    import json
    
    dic = {'k1':'v1','k2':'v2','k3':'v3'}
    str_dic = json.dumps(dic)               # 序列化:将一个字典转换成一个字符串
    print(type(str_dic),str_dic)            # <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
    # 注意,json转换完的字符串类型的字典中的字符串是由""表示的
    
    [2] 将字符串类型的字典转换成字典类型
    import json
    
    dic2 = json.loads(str_dic)      # 反序列化:将一个字符串格式的字典转换成一个字典
    print(type(dic2),dic2)          # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    # 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
    
    [3] 还支持列表类型
    import json
    
    list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
    str_dic = json.dumps(list_dic)                         # 序列化,也可以处理嵌套的数据类型 
    print(type(str_dic),str_dic)                           # <class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
    list_dic2 = json.loads(str_dic)                        # 反序列化
    print(type(list_dic2),list_dic2)                       # <class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
    

    2> dump、load

    [1] 将对象转换成字符串写入到文件当中
    import json
    
    f = open('json_file.json','w')
    dic = {'k1':'v1','k2':'v2','k3':'v3'}
    json.dump(dic,f)                       # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
    f.close()
    # json文件也是文件,就是专门存储json字符串的文件。
    
    [2] 将文件中的字符串类型的字典转换成字典
    import json
    
    f = open('json_file.json')
    dic2 = json.load(f)          # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
    f.close()
    print(type(dic2),dic2)
    
    其他参数说明
    `ensure_ascii`:,当它为True的时候,所有非ASCII码字符显示为uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。 
    `separators`:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(,,:);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。 
    `sort_keys`:将数据根据keys的值进行排序。
    

    json序列化存储多个数据到同一个文件中

    对于json序列化,存储多个数据到一个文件中是有问题的,默认一个json文件只能存储一个json数据,但是也可以解决,举例说明:

    # 对于json 存储多个数据到文件中
    
    dic1 = {'name':'yong1'}
    dic2 = {'name':'yong2'}
    dic3 = {'name':'yong3'}
    ## 写入
    f = open('序列化',encoding='utf-8',mode='a')
    json.dump(dic1,f)
    json.dump(dic2,f)
    json.dump(dic3,f)
    f.close()
    ## 读取
    f = open('序列化',encoding='utf-8')
    ret = json.load(f)
    ret1 = json.load(f)
    ret2 = json.load(f)
    print(ret)
    
    # 注意: 上边的代码会报错,解决方法如下:
    
    dic1 = {'name':'yong1'}
    dic2 = {'name':'yong2'}
    dic3 = {'name':'yong3'}
    ## 写入
    f = open('序列化',encoding='utf-8',mode='a')
    str1 = json.dumps(dic1)
    f.write(str1+'
    ')
    str2 = json.dumps(dic2)
    f.write(str2+'
    ')
    str3 = json.dumps(dic3)
    f.write(str3+'
    ')
    f.close()
    ## 读取
    f = open('序列化',encoding='utf-8')
    for line in f:
        print(json.loads(line))
    

    (4)pickle模块

    <1> pickle模块是将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去

    <2> 只有Python有,几乎可以序列Python中所有数据类型,匿名函数不能序列

    # 使用上与json几乎差不多,也是两对四个方法。
    dumps   loads    # ----  用于网络传输
    dump     load    # ----  用于文件存储
    

    1> dumps、loads

    import pickle
    
    dic = {'k1':'v1','k2':'v2','k3':'v3'}
    str_dic = pickle.dumps(dic)   # 序列化
    print(str_dic)                # bytes类型
    
    dic2 = pickle.loads(str_dic)  # 反序列化
    print(dic2)                   # 字典
    
    # 还可以序列化对象
    
    def func():
        print(666)
    
    ret = pickle.dumps(func)
    print(ret,type(ret))         # b'x80x03c__main__
    func
    qx00.' <class 'bytes'>
    f1 = pickle.loads(ret)       # f1得到 func函数的内存地址
    f1()                         # 执行func函数
    

    2> dump、load

    import pickle
    
    dic = {(1,2):'yong',1:True,'set':{1,2,3}}
    f = open('pick序列化',mode='wb')
    pickle.dump(dic,f)
    f.close()
    
    with open('pick序列化',mode='wb') as f1:
        pickle.dump(dic,f1)
    

    pickle序列化存储多个数据到一个文件中

    import pickle
    
    dic1 = {'name':'yong1'}
    dic2 = {'name':'yong2'}
    dic3 = {'name':'yong3'}
    # 写入
    f = open('pick多数据',mode='wb')
    pickle.dump(dic1,f)
    pickle.dump(dic2,f)
    pickle.dump(dic3,f)
    f.close()
    # 读取
    f = open('pick多数据',mode='rb')
    while True:
        try:
            print(pickle.load(f))
        except EOFError:
            break
    f.close()
    

    自写一个pickle写入文件上下文

    import pickle
    
    class MyPickle:
        def __init__(self,path,mode='load'):
            self.path = path
            self.mode = 'ab' if mode=='dump' else 'rb'
    
        def __enter__(self):
            self.f = open(self.path, mode=self.mode)
            return self
    
        def dump(self,content):
            pickle.dump(content,self.f)
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            self.f.close()
    
        def __iter__(self):
            while True:
                try:
                    yield  pickle.load(self.f)
                except EOFError:
                    break
    
    
    class Course:
        def __init__(self,name,price,period):
            self.name = name
            self.price = price
            self.period = period
    
    python = Course('python',19800,'6 months')
    linux = Course('linux',19800,'6 months')
    
    
    with MyPickle('course_file') as p:
        for obj in p:
            print(obj.__dict__)
    with MyPickle('course_file','dump') as p:
        p.dump(python)
        p.dump(linux)
    
    with open('course_file','ab') as f:
        pickle.dump(linux,f)
    
    with open('course_file','rb') as f:
        while True:
            try:
                obj = pickle.load(f)
                print(obj.__dict__)
            except EOFError:
                break
    

    注: json是一种所有的语言都可以识别的数据结构。如将一个字典序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。但是如果用pickle进行序列化,其他语言就不能读懂这是什么了。因此,如果序列化的内容是列表或者字典,非常推荐使用json模块,但如果出于某种原因不得不序列化其他的数据类型,而未来确定还会用python对这个数据进行反序列化的话,那么就可以使用pickle。

  • 相关阅读:
    spring data实现自定义的repository实现类,实现跟jpa联通
    SQLYog快捷键大全
    JSP 中EL表达式用法详解
    java中的标记接口
    单元测试中快速执行某个方法
    Spring Boot 以 jar 包方式运行在后台
    Spring Data JPA
    扩展spring data jpa的数据更新方法时注意事项
    在Spring Data JPA 中使用Update Query更新实体类
    高速创建和mysql表相应的java domain实体类
  • 原文地址:https://www.cnblogs.com/caiyongliang/p/11506378.html
Copyright © 2011-2022 走看看