Pergunta

Usar o módulo Shelve me deu um comportamento surpreendente. keys (), iter () e iteritems () não retornam todas as entradas na prateleira! Aqui está o código:

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

mais tarde:

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

E aqui está a saída:

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

Alguém já encontrou isso antes e há uma solução alternativa sem saber todas as teclas de cache possíveis a priori?

Foi útil?

Solução

De acordo com Referência da Biblioteca Python:

... O banco de dados também está (infelizmente) sujeito às limitações do DBM, se for usado - isso significa que (a representação em conserva de) os objetos armazenados no banco de dados devem ser bastante pequenos ...

Isso reproduz corretamente o '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()

com a saída:

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

A resposta, portanto, é não armazenar nada grande - como XML bruto -, mas os resultados dos cálculos em uma prateleira.

Outras dicas

Vendo seus exemplos, meu primeiro pensamento é que cache.has_key() tem efeitos colaterais, ou seja, essa chamada adicionará teclas ao cache. O que você ganha

print cache.has_key('xxx')
print list(cache.keys())
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top