¿Problema con el módulo de Shelve?
Pregunta
El uso del módulo de Shelve me ha dado un comportamiento sorprendente. Keys (), iter () y iteritems () ¡No devuelvan todas las entradas en el estante! Aquí está el código:
cache = shelve.open('my.cache')
# ...
cache[url] = (datetime.datetime.today(), value)
luego:
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()
Y aquí está la salida:
['targets.xml']
['accounts_with_transactions.xml', 'targets.xml']
['targets.xml', 'accounts_with_transactions.xml']
¿Alguien se ha encontrado con esto antes, y es una solución sin saber todas las claves de caché posibles? a priori?
Solución
De acuerdo con la Referencia de la biblioteca de Python:
... La base de datos también (desafortunadamente) está sujeta a las limitaciones de DBM, si se usa, esto significa que (la representación en escabeche de) los objetos almacenados en la base de datos deberían ser bastante pequeños ...
Esto reproduce correctamente el 'error':
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()
con la salida:
[]
['trxns.xml', 'foobar.xml']
['foobar.xml', 'trxns.xml']
La respuesta, por lo tanto, es no almacenar nada grande, como el XML crudo, sino más bien los resultados de los cálculos en un estante.
Otros consejos
Al ver tus ejemplos, mi primer pensamiento es que cache.has_key()
tiene efectos secundarios, es decir, esta llamada agregará claves al caché. Que obtienes por
print cache.has_key('xxx')
print list(cache.keys())