Domanda

L'uso del modulo Shelve mi ha dato un comportamento sorprendente. keys (), iter () e iteritems () non restituire tutte le voci nello scaffale! Ecco il codice:

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

dopo:

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()

Ed ecco l'output:

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

Qualcuno ha già incontrato questo prima, ed è una soluzione alternativa senza conoscere tutte le chiavi della cache possibili a priori?

È stato utile?

Soluzione

Secondo il Riferimento della Biblioteca Python:

... Il database è anche (purtroppo) soggetto ai limiti di DBM, se viene utilizzato - ciò significa che (la rappresentazione in salamoia di) gli oggetti memorizzati nel database dovrebbero essere abbastanza piccoli ...

Questo riproduce correttamente il "bug":

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 l'output:

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

La risposta, quindi, non è immagazzinare nulla di grande, come XML grezzo, ma piuttosto i risultati dei calcoli in uno scaffale.

Altri suggerimenti

Vedendo i tuoi esempi, il mio primo pensiero è quello cache.has_key() Ha effetti collaterali, cioè questa chiamata aggiungerà chiavi alla cache. Cosa ottieni

print cache.has_key('xxx')
print list(cache.keys())
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top