如何在Python中使用Pickle进行对象序列化?

2021年11月16日20:42:30 发表评论 762 次浏览

Python Pickle如何进行对象序列化?使用 Python 标准库 pickle 模块在 Python 中保存(pickle)和加载(unpickle)任何类型的对象。

如何使用Pickle序列化对象对象序列化是将数据结构或对象状态转换为可以存储在文件中或稍后传输和重建的格式的过程。在本教程中,你将学习如何使用pickle内置模块在 Python 中序列化和反序列化对象。

Python 中的序列化通常称为picklingPickling只是将 Python 对象层次结构转换为字节流的过程,而unpickling是相反的操作。

相关:如何在 Python 中压缩和解压缩文件。

Python Pickle对象序列化示例介绍 - 让我们从腌制基本的 Python 数据结构开始:

import pickle

# define any Python data structure including lists, sets, tuples, dicts, etc.
l = list(range(10000))

Python Pickle如何进行对象序列化?我在这里使用了一个包含10000 个元素的列表,仅用于演示目的,你可以使用任何 Python 对象,以下代码将此列表保存到文件中:

# save it to a file
with open("list.pickle", "wb") as file:
    pickle.dump(l, file)

和pickle.dump(OBJ,文件)写的腌代表的obj(在这种情况下,列表)来打开的文件(在写,字节模式“WB”),再一次让我们负担这个对象:

# load it again
with open("list.pickle", "rb") as file:
    unpickled_l = pickle.load(file)

pickle.load(file)从存储在文件中的 pickle 数据读取并返回一个对象(以读取和字节模式"rb"打开),比较原始对象和 unpickled 对象:

print("unpickled_l == l: ", unpickled_l == l)
print("unpickled l is l: ", unpickled_l is l)

输出:

如何在Python中使用Pickle进行对象序列化?
unpickled_l == l:  True
unpickled l is l:  False

有道理,列表的值仍然相同(相等),但并不完全相同,换句话说,unpickled 列表在内存中有另一个位置,因此它实际上是原始对象的副本。

你还可以保存和加载用户定义类的对象实例。例如,让我们定义一个简单的Person类:

class Person:
    def __init__(self, first_name, last_name, age, gender):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.gender = gender

    def __str__(self):
        return f"<Person name={self.first_name} {self.last_name}, age={self.age}, gender={self.gender}>"

p = Person("John", "Doe", 99, "Male")

让我们再次进行相同的过程:

# save the object
with open("person.pickle", "wb") as file:
    pickle.dump(p, file)

# load the object
with open("person.pickle", "rb") as file:
    p2 = pickle.load(file)

print(p)
print(p2)

这输出:

<Person name=John Doe, age=99, gender=Male>
<Person name=John Doe, age=99, gender=Male>

Python Pickle对象序列化示例解析 - 一般情况下,如果要对用户定义的特定对象进行 unpickle,则需要在当前作用域中实现其类,否则会引发错误。

例如,如果你解压一个 NumPy 数组(或你安装的模块内的任何其他已定义对象),Python 将自动导入 NumPy 模块并为你加载该对象。

Python Pickle如何进行对象序列化?你还可以使用pickle.dumps(obj)函数,该函数将对象的pickle 表示返回为bytes 对象,因此你可以对其进行加密、传输或其他任何操作。下面的代码使用pickle.dumps(obj)和pickle.loads(data)函数pickle和unpickles前一个对象:

# get the dumped bytes
dumped_p = pickle.dumps(p)
print(dumped_p)

# write them to a file
with open("person.pickle", "wb") as file:
    file.write(dumped_p)

# load it
with open("person.pickle", "rb") as file:
    p2 = pickle.loads(file.read())

如何使用Pickle序列化对象?看一下该对象的字节表示:

b'\x80\x03c__main__\nPerson\nq\x00)\x81q\x01}q\x02(X\n\x00\x00\x00first_nameq\x03X\x04\x00\x00\x00Johnq\x04X\t\x00\x00\x00last_nameq\x05X\x03\x00\x00\x00Doeq\x06X\x03\x00\x00\x00ageq\x07KcX\x06\x00\x00\x00genderq\x08X\x04\x00\x00\x00Maleq\tub.'

是的,没错,不是人类可读的,那是因为它是二进制格式。

最后,这里是你可以pickle和unpickle的对象列表:

  • none。
  • 布尔变量(True和False)。
  • 整数、浮点数和复数。
  • 字符串、字节、字节数组。
  • 仅包含可pickle对象的元组、列表、集合和字典。
  • 在模块顶层定义的函数(使用def,而不是lambda)。
  • 在模块顶层定义的内置函数(例如max、min、bool等)。
  • 在模块顶层定义的类。

有关更多信息,请参阅官方 Python 文档

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: