Python Language
accantonare
Ricerca…
introduzione
Shelve è un modulo python utilizzato per memorizzare oggetti in un file. Il modulo shelve implementa l'archiviazione persistente per oggetti Python arbitrari che possono essere decapitati utilizzando un'API simile a un dizionario. Il modulo shelve può essere usato come una semplice opzione di memorizzazione persistente per oggetti Python quando un database relazionale è eccessivo. Lo scaffale è accessibile tramite i tasti, proprio come con un dizionario. I valori vengono decapitati e scritti in un database creato e gestito da anydbm.
Osservazioni
Nota: non fare affidamento sul fatto che lo scaffale venga chiuso automaticamente; chiama sempre close()
esplicitamente quando non ne hai più bisogno, o usa shelve.open()
come gestore del contesto:
with shelve.open('spam') as db:
db['eggs'] = 'eggs'
Avvertimento:
Poiché il modulo shelve
è supportato da pickle
, non è sicuro caricare un ripiano da una fonte non affidabile. Come con pickle, il caricamento di uno scaffale può eseguire codice arbitrario.
restrizioni
1 . La scelta del pacchetto di database che verrà utilizzato (come dbm.ndbm o dbm.gnu) dipende da quale interfaccia è disponibile. Pertanto non è sicuro aprire il database direttamente usando dbm. Il database è anche (sfortunatamente) soggetto alle limitazioni di dbm, se viene usato - questo significa che (la rappresentazione in pickled di) gli oggetti memorizzati nel database dovrebbero essere abbastanza piccoli, e in rari casi le collisioni di chiavi possono causare il database rifiutare gli aggiornamenti.
2. Il modulo shelve non supporta l'accesso simultaneo in lettura / scrittura agli oggetti accantonati. (Gli accessi multipli simultanei in lettura sono sicuri). Quando un programma ha uno scaffale aperto per la scrittura, nessun altro programma dovrebbe averlo aperto per la lettura o la scrittura. Il blocco dei file Unix può essere utilizzato per risolvere questo problema, ma questo differisce tra le versioni di Unix e richiede la conoscenza dell'implementazione del database utilizzata.
Codice di esempio per shelve
Per accantonare un oggetto, prima importa il modulo e poi assegna il valore dell'oggetto come segue:
import shelve
database = shelve.open(filename.suffix)
object = Object()
database['key'] = object
Per riepilogare l'interfaccia (la chiave è una stringa, i dati sono un oggetto arbitrario):
import shelve
d = shelve.open(filename) # open -- file may get suffix added by low-level
# library
d[key] = data # store data at key (overwrites old data if
# using an existing key)
data = d[key] # retrieve a COPY of data at key (raise KeyError
# if no such key)
del d[key] # delete data stored at key (raises KeyError
# if no such key)
flag = key in d # true if the key exists
klist = list(d.keys()) # a list of all existing keys (slow!)
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2] # this works as expected, but...
d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
# having opened d without writeback=True, you need to code carefully:
temp = d['xx'] # extracts the copy
temp.append(5) # mutates the copy
d['xx'] = temp # stores the copy right back, to persist it
# or, d=shelve.open(filename,writeback=True) would let you just code
# d['xx'].append(5) and have it work as expected, BUT it would also
# consume more memory and make the d.close() operation slower.
d.close() # close it
Creare un nuovo scaffale
Il modo più semplice per usare shelve è tramite la classe DbfilenameShelf . Usa anydbm per memorizzare i dati. Puoi usare direttamente la classe, o semplicemente chiamare shelve.open () :
import shelve
s = shelve.open('test_shelf.db')
try:
s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }
finally:
s.close()
Per accedere nuovamente ai dati, apri lo scaffale e usalo come un dizionario:
import shelve
s = shelve.open('test_shelf.db')
try:
existing = s['key1']
finally:
s.close()
print existing
Se esegui entrambi gli script di esempio, dovresti vedere:
$ python shelve_create.py
$ python shelve_existing.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
Il modulo dbm non supporta più applicazioni che scrivono nello stesso database contemporaneamente. Se sai che il tuo cliente non modificherà lo scaffale, puoi dire a shelve di aprire il database in sola lettura.
import shelve
s = shelve.open('test_shelf.db', flag='r')
try:
existing = s['key1']
finally:
s.close()
print existing
Se il programma tenta di modificare il database mentre è aperto in sola lettura, viene generata un'eccezione di errore di accesso. Il tipo di eccezione dipende dal modulo del database selezionato da anydbm quando il database è stato creato.
Rispondere
Gli scaffali non tengono traccia delle modifiche agli oggetti volatili, per impostazione predefinita. Ciò significa che se si modifica il contenuto di un elemento archiviato nello scaffale, è necessario aggiornare lo scaffale in modo esplicito memorizzando nuovamente l'elemento.
import shelve
s = shelve.open('test_shelf.db')
try:
print s['key1']
s['key1']['new_value'] = 'this was not here before'
finally:
s.close()
s = shelve.open('test_shelf.db', writeback=True)
try:
print s['key1']
finally:
s.close()
In questo esempio, il dizionario in 'key1' non viene memorizzato di nuovo, quindi quando lo shelf viene riaperto, le modifiche non sono state mantenute.
$ python shelve_create.py
$ python shelve_withoutwriteback.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
Per rilevare automaticamente le modifiche agli oggetti volatili memorizzati nello scaffale, aprire lo scaffale con writeback abilitato. L'indicatore writeback fa sì che lo scaffale ricordi tutti gli oggetti recuperati dal database utilizzando una cache in memoria. Ogni oggetto cache viene anche riscritto nel database quando lo shelf è chiuso.
import shelve
s = shelve.open('test_shelf.db', writeback=True)
try:
print s['key1']
s['key1']['new_value'] = 'this was not here before'
print s['key1']
finally:
s.close()
s = shelve.open('test_shelf.db', writeback=True)
try:
print s['key1']
finally:
s.close()
Sebbene riduca le possibilità di errore del programmatore e possa rendere la persistenza degli oggetti più trasparente, l'uso della modalità writeback potrebbe non essere desiderabile in ogni situazione. La cache consuma memoria aggiuntiva mentre lo scaffale è aperto e la pausa per scrivere ogni oggetto memorizzato nella cache al database quando viene chiusa può richiedere più tempo. Poiché non c'è modo di sapere se gli oggetti memorizzati nella cache sono stati modificati, vengono tutti riscritti. Se l'applicazione legge più dati di quanti ne scrive, la riscrittura aggiungerà un sovraccarico maggiore di quanto si possa desiderare.
$ python shelve_create.py
$ python shelve_writeback.py
{'int': 10, 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}
{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}