Python 数据持久化 - Pickle 模块

Python 的序列化和反序列化术语分别是 pickling 和 unpickling。 Python 库中的 pickle 模块,使用非常 Python 特定的数据格式。 因此,非 Python 应用程序可能无法正确反序列化 pickled 数据。 建议不要从未经身份验证的来源中提取数据。

序列化(pickled)数据可以存储在字节串或二进制文件中。 该模块定义了 dumps()loads() 函数以使用字节字符串对数据进行 pickle 和 unpickle。 对于基于文件的进程,该模块具有dump()load() 函数。

Python 的 pickle 协议是用于将 Python 对象构造为二进制数据或从二进制数据解构的约定。 目前,pickle 模块定义了 5 种不同的协议,如下所列 −

序号 名称 & 描述
1

Protocol version 0

与早期版本向后兼容的原始"human-readable"(人类可读)协议。

2

Protocol version 1

旧的二进制格式也与早期版本的 Python 兼容。

3

Protocol version 2

在 Python 2.3 中引入,提供新型类的高效 pickling。

4

Protocol version 3

在 Python 3.0 中添加。 当需要与其他 Python 3 版本兼容时推荐使用。

5

Protocol version 4

是在 Python 3.4 中添加的。 它增加了对非常大的对象的支持


示例

pickle 模块由 dumps() 函数组成,该函数返回 pickle 数据的字符串表示形式。

from pickle import dump
dct={"name":"Ravi", "age":23, "Gender":"M","marks":75}
dctstring=dumps(dct)
print (dctstring)

输出

b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00Raviq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x06\x00\x00\x00Genderq\x04X\x01\x00\x00\x00Mq\x05X\x05\x00\x00\x00marksq\x06KKu.

示例

使用loads()函数,对字符串进行unpickle,获取原始字典对象。

from pickle import load
dct=loads(dctstring)
print (dct)

输出

{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}

Pickled 对象也可以使用 dump() 函数持久存储在磁盘文件中,并使用 load() 函数检索。

import pickle
f=open("data.txt","wb")
dct={"name":"Ravi", "age":23, "Gender":"M","marks":75}
pickle.dump(dct,f)
f.close()

#to read
import pickle
f=open("data.txt","rb")
d=pickle.load(f)
print (d)
f.close()

pickle 模块还以 PicklerUnpickler 类的形式为序列化机制提供面向对象的 API。

如上所述,就像Python中的内置对象一样,用户定义类的对象也可以在磁盘文件中持久序列化。 在下面的程序中,我们定义了一个 User 类,以姓名和手机号码作为其实例属性。 除了 __init__() 构造函数之外,该类还覆盖了 __str__() 方法,该方法返回其对象的字符串表示形式。

class User:
   def __init__(self,name, mob):
      self.name=name
      self.mobile=mob
   def __str__(self):
return ('Name: {} mobile: {} '. format(self.name, self.mobile))

为了在文件中腌制上述类的对象,我们使用 pickler 类及其 dump() 方法。

from pickle import Pickler
user1=User('Rajani', 'raj@gmail.com', '1234567890')
file=open('userdata','wb')
Pickler(file).dump(user1)
Pickler(file).dump(user2)
file.close()

相反,Unpickler 类有 load() 方法来检索序列化对象,如下所示 −

from pickle import Unpickler
file=open('usersdata','rb')
user1=Unpickler(file).load()
print (user1)