shelve模块出现问题?

2 投票
2 回答
1014 浏览
提问于 2025-04-15 13:51

使用shelve模块时,我遇到了一些意想不到的情况。调用keys()、iter()和iteritems()这些方法时,并没有返回所有的条目!下面是我的代码:

cache = shelve.open('my.cache')
# ...
cache[url] = (datetime.datetime.today(), value)

稍后:

cache = shelve.open('my.cache')
urls = ['accounts_with_transactions.xml', 'targets.xml', 'profile.xml']
try:
    print list(cache.keys()) # doesn't return all the keys!
    print [url for url in urls if cache.has_key(url)]
    print list(cache.keys())
finally:
    cache.close()

这是输出结果:

['targets.xml']
['accounts_with_transactions.xml', 'targets.xml']
['targets.xml', 'accounts_with_transactions.xml']

有没有人遇到过这个问题?有没有什么解决办法,不需要事先知道所有可能的缓存键?

2 个回答

0

看到你的例子,我首先想到的是 cache.has_key() 这个方法可能会有副作用,也就是说,调用这个方法可能会往缓存里添加一些键。你得到的结果是什么呢?

print cache.has_key('xxx')
print list(cache.keys())
3

根据Python库的参考资料

...如果使用了dbm,这个数据库也(不幸地)受到它的限制——这意味着存储在数据库中的对象(经过序列化后的表示)应该相对较小...

这就正确地复现了“错误”:

import shelve

a = 'trxns.xml'
b = 'foobar.xml'
c = 'profile.xml'

urls = [a, b, c]
cache = shelve.open('my.cache', 'c')

try:
    cache[a] = a*1000
    cache[b] = b*10000
finally:
    cache.close()


cache = shelve.open('my.cache', 'c')

try:
    print cache.keys()
    print [url for url in urls if cache.has_key(url)]
    print cache.keys()
finally:
    cache.close()

输出结果是:

[]
['trxns.xml', 'foobar.xml']
['foobar.xml', 'trxns.xml']

所以,答案就是不要存储任何大的东西——比如原始的xml——而是把计算的结果存放在一个shelf里。

撰写回答