2009-08-25 4 views
2

Die Verwendung des Regalmoduls hat mir ein überraschendes Verhalten gegeben. keys(), iter() und iteritems() geben nicht alle Einträge im Regal zurück! Hier ist der Code:Problem mit Regalmodul?

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

später:

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

und hier ist die Ausgabe:

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

Hat jemand in diese vor laufen, und gibt es eine Abhilfe, ohne alle möglichen Cache-Schlüssel zu wissen, a priori?

+0

Welches DBM-Modul verwenden Sie? Klingt für mich wie ein Käfer. –

+0

whichdb.whichdb ('my.cache') => dbm –

+0

(übrigens, das ist Python 2.5 auf einem Mac) –

Antwort

3

Nach dem python library reference:

... Die Datenbank ist auch (leider) vorbehaltlich der Einschränkungen von dbm, wenn es verwendet wird - dies bedeutet, dass (die gebeizt Darstellung), die in der Datenbank gespeicherten Objekte sollte ziemlich klein sein ...

Dieses korrekt reproduziert die ‚Fehler‘:

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

mit dem Ausgang:

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

Die Antwort ist also nicht speichert etwas groß-wie rohen xml-sondern Ergebnisse von Berechnungen in einem Regal.

+0

In Python 2.6 kann ich diesen "Fehler" nicht reproduzieren. – NicDumZ

+0

Möglicherweise verwenden Sie nicht dbm, versuchen Sie whatdb.whichdb ('my.cache'). Auf meinem Mac produziert es "dbm". Ich habe es noch nicht auf anderen Systemen ausprobiert. –

0

Ich sehe Ihre Beispiele, mein erster Gedanke ist, dass cache.has_key() Nebenwirkungen hat, d. H. Dieser Anruf wird Schlüssel zum Cache hinzufügen. Was bekommen Sie für

print cache.has_key('xxx') 
print list(cache.keys()) 
+0

Ich aktualisierte den Fragecode mit einer abgekürzten Version von URLs –

+0

Berechnet immer noch nicht; Sie fügen dem Cache eine einzelne URL hinzu, aber nach "has_key" hat der Cache zwei URLs. Es muss einige Nebeneffekte geben. –

+0

Der Cache hat tatsächlich 2 URLs drin. aber keys() zeigt sie nicht beide, bis ich für jeden explizit teste. –