Sto cercando consigli sui metodi di implementazione della persistenza dell'oggetto in Python. Per essere più precisi, desidero essere in grado di collegare un oggetto Python a un file in modo tale che qualsiasi processo Python che apre una rappresentazione di quel file condivida le stesse informazioni, qualsiasi processo possa cambiare il suo oggetto e le modifiche si propagheranno a gli altri processi e anche se tutti i processi "memorizzano" l'oggetto sono chiusi, il file rimarrà e potrà essere riaperto da un altro processo.Persistenza oggetto Python
Ho trovato tre candidati principali per questo nella mia distribuzione di Python - anydbm, pickle e shelve (dbm sembrava perfetto, ma è solo per Unix e io sono su Windows). Tuttavia, tutti hanno difetti:
- anydbm può gestire solo un dizionario di valori stringa (sto cercando di memorizzare un elenco di dizionari, che hanno tutti le chiavi stringa e valori di stringa, anche se idealmente vorrei cercare un modulo senza restrizioni di tipo)
- shelve richiede che un file venga riaperto prima della propagazione delle modifiche - ad esempio, se due processi A e B caricano lo stesso file (contenente una lista vuota accantonata) e A aggiunge un elemento al elenca e chiama sync(), B vedrà comunque l'elenco come vuoto finché non ricaricherà il file.
- pickle (il modulo attualmente utilizzato per l'implementazione del test) ha lo stesso "requisito di ricarica" come shelve e non sovrascrive i dati precedenti, se il processo A scarica quindici stringhe vuote su un file e quindi la stringa " ciao ', il processo B dovrà caricare il file sedici volte per ottenere la stringa' ciao '. Attualmente mi occupo di questo problema precedendo qualsiasi operazione di scrittura con letture ripetute fino alla fine del file ("pulendo la lavagna pulita prima di scriverle sopra") e facendo ogni operazione di lettura ripetuta fino alla fine del file, ma ritengo che ci debba essere un modo migliore.
mio modulo ideale sarebbe comportarsi come segue (con "A >>>" codice che rappresenta eseguito dal processo A, e "B >>>" codice eseguito dal processo B):
A>>> import imaginary_perfect_module as mod
B>>> import imaginary_perfect_module as mod
A>>> d = mod.load('a_file')
B>>> d = mod.load('a_file')
A>>> d
{}
B>>> d
{}
A>>> d[1] = 'this string is one'
A>>> d['ones'] = 1 #anydbm would sulk here
A>>> d['ones'] = 11
A>>> d['a dict'] = {'this dictionary' : 'is arbitrary', 42 : 'the answer'}
B>>> d['ones'] #shelve would raise a KeyError here, unless A had called d.sync() and B had reloaded d
11 #pickle (with different syntax) would have returned 1 here, and then 11 on next call
(etc. for B)
I potrebbe ottenere questo comportamento creando il mio modulo che utilizza pickle e modificando il dump e il comportamento del caricamento in modo che utilizzino le letture ripetute che ho menzionato sopra, ma trovo difficile credere che questo problema non sia mai stato risolto e risolto da , programmatori più talentuosi prima. Inoltre, queste letture ripetute mi sembrano inefficienti (anche se devo ammettere che la mia conoscenza della complessità operativa è limitata, ed è possibile che queste letture ripetute stiano andando "dietro le quinte" in moduli altrimenti apparentemente più lisci come shelve). Pertanto, concludo che mi manca un modulo di codice che risolva il problema per me. Sarei grato se qualcuno potesse indicarmi la giusta direzione o dare consigli sull'implementazione.
Dare un'occhiata a 'Mongo-db'. Non è completamente integrato nella lingua come nell'esempio sopra riportato, ma fornirà un database molto più robusto e tollerante rispetto al pickling sul filesystem e all'insegna dei lock. – slezica