11.4. shelve-Python 对象持久性

源代码: Lib/shelve.py


“架子”是一个持久的,类似于字典的对象。与“ dbm”数据库的区别在于,架子中的值(不是键!)本质上可以是任意的 Python 对象-pickle模块可以处理的任何对象。这包括大多数类实例,递归数据类型以及包含许多共享子对象的对象。键是普通字符串。

默认情况下,版本 0 的 pickle 用于序列化值。可以使用* protocol *参数指定 pickle 协议的版本。

在版本 2.3 中进行了更改:添加了* protocol *参数。

由于 Python 的语义,货架无法得知何时修改了可变持久词典条目。默认情况下,将修改后的对象分配给书架时仅写入(请参见Example)。如果可选的* writeback *参数设置为True,则所有访问的条目也将缓存在内存中,并写回到sync()close()上;这样可以更容易地更改持久性词典中的可变条目,但是,如果访问了许多条目,则可能会占用大量内存用于缓存,并且由于所有访问的条目都被写回,因此它会使关闭操作非常慢(无法确定哪些访问的条目是可变的,也没有确定哪些实际上是突变的)。

与文件对象一样,应明确关闭 shelve 对象,以确保将持久性数据刷新到磁盘。

Warning

由于shelve模块由pickle支持,因此从不受信任的来源加载书架是不安全的。像 pickle 一样,装载架子可以执行任意代码。

架子对象支持字典支持的大多数方法。这简化了从基于字典的脚本到需要持久存储的脚本的过渡。

请注意,不支持 Python 3 转换方法(viewkeys()viewvalues()viewitems())。

支持两种其他方法:

See also

持久词典配方具有广泛支持的存储格式,并且具有本机字典的速度。

11.4.1. Restrictions

Note

默认情况下,版本 0 的 pickle 用于序列化值。可以使用* protocol *参数指定 pickle 协议的版本。请参阅pickle文档,以获取有关腌制协议的讨论。

在版本 2.3 中进行了更改:添加了* protocol *参数。

如果* writeback 参数为True,则该对象将保留所有已访问条目的缓存,并在同步和关闭时间将它们写回到 dict *。这允许对可变条目进行自然操作,但会消耗更多内存,并使同步和关闭花费很长时间。

11.4.2. Example

总结接口(key是字符串,data是任意对象):

import shelve

d = shelve.open(filename) # open -- file may get suffix added by low-level
                          # library

d[key] = data   # store data at key (overwrites old data if
                # using an existing key)
data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
                # such key)
del d[key]      # delete data stored at key (raises KeyError
                # if no such key)
flag = d.has_key(key)   # true if the key exists
klist = d.keys() # a list of all existing keys (slow!)

# as d was opened WITHOUT writeback=True, beware:
d['xx'] = range(4)  # this works as expected, but...
d['xx'].append(5)   # *this doesn't!* -- d['xx'] is STILL range(4)!

# having opened d without writeback=True, you need to code carefully:
temp = d['xx']      # extracts the copy
temp.append(5)      # mutates the copy
d['xx'] = temp      # stores the copy right back, to persist it

# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.

d.close()       # close it

See also

  • Module anydbm

  • dbm样式数据库的通用接口。

  • Module bsddb

  • BSD db数据库接口。

  • Module dbhash

  • bsddb周围的薄层像其他数据库模块一样提供open()Function。

  • Module dbm

  • 标准 Unix 数据库接口。

  • Module dumbdbm

  • dbm接口的可移植实现。

  • Module gdbm

  • GNU 数据库接口,基于dbm接口。

  • Module pickle

  • shelve使用的对象序列化。

  • Module cPickle

  • pickle的高性能版本。

首页