pickle模块

pickle模块简介

什么是序列化

  • 在程序运行的过程中,所有的变量都是在内存中,比如,定义一个 dict:

    a = {'name':'Bob','age':20,'score':90}
    

    字典 a 可以随时修改变量,比如把 name 改成 'Bill',但是一旦程序结束,变量所占用的内存就被操作系统全部回收。如果没有把修改后的 'Bill'存储到磁盘上,下次重新运行程序,变量又被初始化为 'Bob'

    ==我们把变量从内存中变成可存储或传输的过程称之为序列化,==在 Python 中叫 pickling。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即 unpickling

pickle特点

  • pickle 序列化的程序有什么特点:
    1. pickle 序列化后的数据,可读性差,人一般无法识别;
    2. pickle 模块只能在 python 中使用,且只支持同版本,不能跨平台使用;
    3. Python 中所有的数据类型(列表,字典,集合,类等)都可以用 pickle 来序列化。
    4. 需导入 pickle 模块 — import pickle

pickle模块常用方法

  • pickle常用方法有:
  1. dumps :把 obj 对象序列化后以 bytes 对象返回,不写入文件;
  2. loads:从 bytes 对象中读取一个反序列化对象,并返回其重组后的对象;
  3. dump :序列化对象,并将结果数据流写入到文件对象中;
  4. load :反序列化对象,将文件中的数据解析为一个Python对象。

pickle.dumps(obj)

  • 把 obj 对象序列化后以 bytes 对象返回,不写入文件

    下面代码分别对列表l1、元组t1、字典dic1进行序列化操作,打印后可以看到结果是一堆二进制乱码。代码如下所示:

    import pickle
    
    l1 = [1, 2, 3, 4, 5]
    t1 = (1, 2, 3, 4, 5)
    dic1 = {"k1": "v1", "k2": "v2", "k3": "v3"}
    
    res_l1 = pickle.dumps(l1)
    res_t1 = pickle.dumps(t1)
    res_dic = pickle.dumps(dic1)
    
    print(res_l1)
    print(res_t1)
    print(res_dic)
    

    运行结果如下:

    b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04K\x05e.'
    b'\x80\x03(K\x01K\x02K\x03K\x04K\x05tq\x00.'
    b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.'
    

pickle.loads(bytes_object)

  • 从 bytes 对象中读取一个反序列化对象,并返回其重组后的对象

    下面代码是先分别对列表l1、元组t1、字典dic1进行序列化,然后再对序列化后的对象进行反序列化操作,打印后可以看到序列化之前是什么类型的数据,反序列化后其数据类型不变。代码如下所示:

    import pickle
    
    l1 = [1, 2, 3, 4, 5]
    t1 = (1, 2, 3, 4, 5)
    dic1 = {"k1": "v1", "k2": "v2", "k3": "v3"}
    
    res_l1 = pickle.dumps(l1)
    res_t1 = pickle.dumps(t1)
    res_dic = pickle.dumps(dic1)
    
    print(pickle.loads(res_l1), type(pickle.loads(res_l1)))
    print(pickle.loads(res_t1), type(pickle.loads(res_t1)))
    print(pickle.loads(res_dic), type(pickle.loads(res_dic)))
    

    运行结果如下:

    [1, 2, 3, 4, 5] <class 'list'>
    (1, 2, 3, 4, 5) <class 'tuple'>
    {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} <class 'dict'>
    

pickle.dump(obj , file)

  • 序列化对象,并将结果数据流写入到文件对象中
    下面代码分别把 列表l1、元组t1、字典dic1 进行序列化操作,并保存到一个文件中以实现永久保存。代码入下所示:

    import pickle
    
    l1 = [1, 2, 3, 4, 5]
    t1 = (1, 2, 3, 4, 5)
    dic1 = {"k1": "v1", "k2": "v2", "k3": "v3"}
    # 把列表l1序列化进一个文件f1中
    with open("./f1.pkl", "wb") as f:
        pickle.dump(l1, f)
        pickle.dump(t1, f)
        pickle.dump(dic1, f)
    

    序列化后在当前目录下生成一个f1.pkl文件,打开文件f1可以看到一堆乱码,如下所示:

    ]q(KKKKKe.(KKKKKtq.}q(Xk1qXv1qXk2qXv2qXk3qXv3qu.
    

pickle.load(file)

  • 反序列化对象,将文件中的数据解析为一个Python对象
    下面代码是先对列表l2进行序列化并保存到文件f2.pkl中,然后再对文件f2进行反序列化,得到文件f2里保存的数据

    import pickle
    
    l2 = [1, 2, 3, 4, 5, 6]
    # 把列表l2序列化进一个文件f2中
    with open("f2.pkl", "wb") as f:
        pickle.dump(l2, f)
    with open("f2.pkl", "rb") as f:
        res = pickle.load(f)
        print(res, type(res))
    

    运行结果:

    "反序列化之后,打印数据及其类型可以看到:"
    [1, 2, 3, 4, 5, 6] <class 'list'>
    
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐