如何在 Python 中实现持久对象

如何在 Python 中实现持久对象

在编程中,常常需要将数据保存在磁盘上,以便下次程序运行时提取数据并使用。这就需要使用持久对象,即可以在多次程序执行之间保持状态的对象。Python 为我们提供了多种方式来实现持久对象,本文就介绍其中的两种:pickle 和 shelve。

Pickle

pickle 是 Python 标准库中的一个模块,它可以将 Python 对象序列化成字节流,以便可以将其写入磁盘或发送到网络。反之,也可以将字节流反序列化成 Python 对象。pickle 不仅支持所谓的“普通”对象(数字、字符串、列表等),而且还可以对自定义类进行序列化和反序列化。

序列化

让我们来看一个小例子,假设我们有一个名为 Person 的类,其中有两个属性:姓名和年龄:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

我们创建一个 Person 对象并对其进行序列化:

import pickle

person = Person('Tom', 20)
with open('person.pkl', 'wb') as f:
    pickle.dump(person, f)

这样,我们就将 person 对象序列化到了一个名为 person.pkl 的文件中。下面我们来看看 person.pkl 文件:

这看起来不是很直观,事实上,pickle 默认是将对象以二进制格式存储到文件中的。如果我们想要将这些内容以字符串形式显示,可以使用 pickle.dumps() 方法:

import pickle

person = Person('Tom', 20)
person_str = pickle.dumps(person)
print(person_str)

输出:

b'\x80\x04\x95?\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x06Person\x94\x93\x94\x8c\x04name\x94\x8c\x03Tom\x94\x8c\x03age\x94K\x14\x86\x94.'

反序列化

我们现在有一个名为 person.pkl 的文件,想要将其反序列化为 Python 对象,可以使用 pickle.load() 方法:

import pickle

with open('person.pkl', 'rb') as f:
    person = pickle.load(f)
print(person.name, person.age)

输出:

Tom 20

注意事项

pickle 在序列化 Python 对象时有一些限制。以下是一些最常见的:

  • 无法序列化 lambda、函数和方法。
  • 无法序列化实例方法(由于它们包含对实例的引用)。
  • 无法在不同计算机之间共享 pickle(因为 pickle 包含了 Python 对象的完整表示,而不是二进制数据)。
  • 序列化和反序列化都需要使用相同的 pickle 版本(否则可能会出现错误或不兼容性)。
  • pickle 可能存在安全风险(例如,当加载 pickle 文件时,如果不信任文件源,则 pickle 可能会执行恶意代码)。

Shelve

shelve 模块是 Python 标准库中的一个键值存储模块,顾名思义,它的作用类似于书架:将一系列“书籍”存储在其中,并通过“书名”来查找和获取它们。shelve 可以存储 Python 对象,并将其序列化为字节流,以便可以将其写入磁盘或发送到网络。与 pickle 不同,shelve 存储的是一个个对象,而不是一个个字节流。

存储

让我们来看一个小例子,假设我们有一个名为 Person 的类(与 pickle 中的相同),我们可以使用 shelve 存储多个 Person 对象:

import shelve

with shelve.open('persons') as db:
    db['person1'] = Person('Tom', 20)
    db['person2'] = Person('Jerry', 30)

这里我们使用了 shelve.open() 方法来打开一个名为 persons 的数据库,并使用 db['person1']db['person2'] 来存储两个 Person 对象。保存在磁盘上的数据类似于一个字典,每一个键值对就是一个对象。

获取

我们现在已经将多个 Person 对象存储在了数据库中,我们可以通过键名来获取它们:

import shelve

with shelve.open('persons') as db:
    person1 = db['person1']
    person2 = db['person2']
print(person1.name, person1.age)
print(person2.name, person2.age)

输出:

Tom 20
Jerry 30

注意事项

与 pickle 一样,shelve 存在一些限制和安全问题。以下是一些最常见的:

  • 无法在不同计算机之间共享 shelve(因为它们使用了 Python 内部的数据结构)。
  • 在使用 shelve 时需要注意多线程安全(即需要保证多个线程访问 shelve 数据时没有冲突)。
  • shelve 相比 pickle 明显更慢,因为它需要将 Python 对象转换为字节流和反转换回 Python 对象。

结论

本文介绍了如何在 Python 中使用 pickle 和 shelve 实现持久对象。pickle 可以将 Python 对象序列化为字节流并保存到磁盘上,反之亦然。而 shelve 则是一个键值存储模块,可以存储多个 Python 对象,并通过键名来访问它们。当然,我们也需要注意到它们的限制和安全问题,以便在使用它们的时候避免出现错误。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程