1、pickle 简介

pickle是Python语言的一个标准模块,安装Python后已包含pickle库,不需要单独再安装。 pickle模块是Python专用的持久化模块,可以持久化包括自定义类在内的各种数据,比较适合Python本身复杂数据的存贮。 但是持久化后的字串是不可认读的,并且只能用于Python环境,不能用作与其它语言进行数据交换。

1.1、pickle是什么?

在英语中 pickle 名词是泡菜,动词是腌渍的意思。可以理解为把东西腌起来保存成文件,要用的时候读出来洗洗再用。
Python的pickle模块实现了基本的数据序列化反序列化
序列化对象可以在磁盘上保存对象,并在需要的时候读取出来。任何对象都可以执行序列化操作。

1.2、pickle模块的作用

把 Python 对象直接保存到文件里,而不需要先把它们转化为字符串再保存,也不需要用底层的文件访问操作,直接把它们写入到一个二进制文件里。pickle 模块会创建一个 Python 语言专用的二进制格式,不需要使用者考虑任何文件细节,它会帮你完成读写对象操作。用pickle比你打开文件、转换数据格式并写入这样的操作要节省不少代码行

1.3、pickle的优缺点

优点:

  1. pickle提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
  2. 通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
  3. Python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化。
  4. 没有外部标准强加的限制,例如JSON或XDR(不能代表指针共享)。
  5. 默认情况下,pickle数据格式使用相对紧凑的二进制表示。如果需要最佳尺寸特征,则可以有效地压缩数据。
  6. pickle可以表示极其庞大的Python类型(其中许多是自动的,通过巧妙地使用Python的内省工具;复杂的案例可以通过实现特定的对象API来解决)。
  7. 通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

缺点:

  1. pickle模块只能在Python中使用,仅限于传输的两端都是Python的情况,且需要尽量保持两端的版本一致。
  2. 非Python程序可能无法重建pickled Python对象。
  3. pickle序列化后的数据,可读性差,人一般无法识别。

    1.4、pickle和JSON的区别

  4. JSON是一种文本序列化格式(它输出unicode文本,虽然大部分时间它被编码utf-8),而pickle是二进制序列化格式。

  5. JSON是人类可读的,而pickle则不是。
  6. JSON是可互操作的,并且在Python生态系统之外广泛使用,而pickle是特定于Python的。
  7. 默认情况下,JSON只能表示Python内置类型的子集,而不能表示自定义类;

    1.5、pickle的应用总结

本地序列化的情况,应用较少。一般来说,大多数应用场景在网络中,将数据序列化后通过网络传输到远程结点,远程服务器上的服务接受到数据后进行反序列化,就可以使用了。
但是,需要注意的是,远端接受端反序列化时必须有对应的数据类型,否则就会报错,尤其是自定义类,必须远程存在
目前,大多数项目都不是单机,不是单服务,需要通过网络将数据传送到其他结点上,这就需要大量的序列化,反序列化。
但是python程序之间还可以使用pickle解决序列化和反序列化。
如果是跨平台,跨语言,跨协议,pickle就不适合了,就需要公共协议,如XML/Json /protocol Buffer等。
每种协议都有自己的负载,其所使用的场景都不一样,二进制的操作不一定适用于所有的场景。但越是底层的协议,越需要二进制传输。

2、pickle模块的用法

操作 串行化(序列化) 反串行化(反序列化)
转换+文件操作 dump() load()
转换 dumps() loads()

序列化方法pickle.dump()

序列化的方法为 pickle.dump(),该方法的相关参数如下:

  1. pickle.dump(obj, file, protocol=None,*,fix_imports=True)
  2. # obj 一个Python对象
  3. # file 文件
  4. # protocol 协议
  • 该方法实现的是将序列化后的对象obj以二进制形式写入文件file中,进行保存。
  • 它的功能等同于 Pickler(file, protocol).dump(obj)。
  • 关于参数protocol,一共有5中不同的类型,即(0,1,2,3,4)
    • (0,1,2)对应的是Python早期的版本,
    • (3,4)则是在Python3之后的版本。
  • 关于参数file,有一点需要注意,必须是以二进制的形式进行操作(写入)

    示例:(写入对象到文件)

    ```python import pickle

class User:

  1. def __init__(self, name, city):
  2. self.name = name
  3. self.city = city
  4. def show_own(self):
  5. show_info = "我叫:%s,我来自%s" % (self.name, self.city)
  6. return show_info

xiaoxin = User(“小新同学”, “北京市”)

with open(“userinfo.txt”, “wb”) as fw: # “wb”以二进制的形式进行操作(写入) pickle.dump(xiaoxin,fw) # 将User的实例对象xiaoxin 存入文件中

  1. <a name="CnsNC"></a>
  2. ## 反序列化方法pickle.load()
  3. - 该方法实现的是将序列化的对象从文件file中读取出来。
  4. - 它的功能等同于 Unpickler(file).load()。
  5. - 关于参数file,有一点需要注意,必须是以二进制的形式进行操作(读取)。
  6. <a name="P4bXn"></a>
  7. ### 示例:(从文件读取对象)
  8. ```python
  9. import pickle
  10. class User:
  11. def __init__(self, name, city):
  12. self.name = name
  13. self.city = city
  14. def show_own(self):
  15. show_info = "我叫:%s,我来自%s" % (self.name, self.city)
  16. return show_info
  17. xiaoxin = User("小新同学", "北京市")
  18. # with open("userinfo.txt", "wb") as fw: # "wb"以二进制的形式进行操作(写入)
  19. # pickle.dump(xiaoxin,fw)
  20. with open("userinfo.txt", "rb") as fr:
  21. new_user = pickle.load(fr)
  22. print(new_user.name)
  23. print(new_user.city)
  24. print(new_user.show_own())

image.png

序列化方法pickle.dumps()

  1. pickle.dumps(obj, protocol=None,*,fix_imports=True)
  2. # obj 一个Python对象
  3. # file 文件
  4. # protocol 协议

pickle.dumps()方法跟pickle.dump()方法的区别在于,
pickle.dumps()方法不需要写入文件中,它是直接返回一个序列化的bytes对象

示例:(写入对象到文件)

  1. import pickle # 导入pickle模块
  2. class User:
  3. def __init__(self,name,city):
  4. self.name = name
  5. self.city = city
  6. def show_own(self):
  7. show_info = "我叫:%s,我来自%s"%(self.name,self.city)
  8. return show_info
  9. xiaoxin = User("小新同学","北京市")
  10. with open("userinfo.txt","wb")as fw: # "wb"以二进制的形式进行操作(写入)
  11. fw.write(pickle.dumps(xiaoxin)) # 将User的实例对象xiaoxin 存入文件中

image.png

反序列化方法pickle.loads()

pickle.loads()方法跟pickle.load()方法的区别在于,
pickle.loads()方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。

示例:(从文件读取对象)

  1. import pickle
  2. class User:
  3. def __init__(self, name, city):
  4. self.name = name
  5. self.city = city
  6. def show_own(self):
  7. show_info = "我叫:%s,我来自%s" % (self.name, self.city)
  8. return show_info
  9. xiaoxin = User("小新同学", "北京市")
  10. # with open("userinfo.txt", "wb") as fw: # "wb"以二进制的形式进行操作(写入)
  11. # fw.write(pickle.dumps(xiaoxin))
  12. with open("userinfo.txt", "rb") as fr: # "rb"以二进制的形式进行操作(读取)
  13. new_user = pickle.loads(fr.read()) # 从文件中读取对象
  14. print(new_user.name)
  15. print(new_user.city)
  16. print(new_user.show_own())

image.png

参考博客:

CSDN:python pickle用法_Python的pickle模块详解(包括优缺点及和JSON的区别)
https://blog.csdn.net/weixin_36115496/article/details/114912062
脚本之家:Python 中Pickle库的使用详解
https://www.jb51.net/article/135407.htm