Вопрос
Использование модуля полки дало мне некоторое удивительное поведение. 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']
Кто -нибудь сталкивался с этим раньше, и есть ли обходной путь, не зная всех возможных ключей кеша априори?
Решение
Согласно Ссылка на библиотеку 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 - но скорее результаты расчетов на полке.
Другие советы
Видя ваши примеры, моя первая мысль - это то, что cache.has_key()
Имеет побочные эффекты, то есть этот вызов добавит ключи в кеш. Что ты получаешь
print cache.has_key('xxx')
print list(cache.keys())