2009-02-10 14 views
7

Tutto quello che voglio fare è serializzare e unserializzare tuple di stringhe o int.Pickle leggero per i tipi base in python?

Ho esaminato pickle.dumps() ma l'overhead di byte è significativo. Fondamentalmente sembra che occupi circa 4 volte lo spazio necessario. Inoltre, tutto ciò di cui ho bisogno sono i tipi di base e non ho bisogno di serializzare oggetti.

marshal è un po 'meglio in termini di spazio ma il risultato è pieno di brutti byte \ x00. Idealmente, mi piacerebbe che il risultato fosse leggibile.

Ho pensato di usare solo repr() ed eval(), ma c'è un modo semplice per farlo senza usare eval()?

Viene memorizzato in un file db, non in un file. Il sovraccarico del byte è importante perché potrebbe fare la differenza tra richiedere una colonna TEXT rispetto a un varchar e generalmente la compattezza dei dati interessa tutte le aree delle prestazioni del db.

+0

l'overhead * è * significativo per una discarica di pickle! –

+2

Il grafico Bristol Stool è un'ottima risorsa per identificare il tipo di brutto \ x00 byte che potresti incontrare http://en.wikipedia.org/wiki/File:Bristol_Stool_Chart.png –

+0

dove si trova il problema con il configparser? –

risposta

13

Dai uno sguardo allo json, almeno lo dumps generato è leggibile con molte altre lingue.

JSON (JavaScript Object Notation) http://json.org è un sottoinsieme della sintassi JavaScript (ECMA-262 3a edizione) utilizzato come formato di interscambio di dati leggero.

1

Ci sono alcuni builtin di persistenza menzionati nello python documentation ma non penso che nessuno di questi sia considerevolmente più piccolo nella dimensione del file prodotto.

Si potrebbe sempre usare lo configparser ma si ottiene solo stringhe, int, float, bool.

0

"l'overhead byte è significativo"

Perché questo tema? Fa il lavoro. Se stai esaurendo lo spazio su disco, sarei felice di venderti 1 TB a $ 500.

Avete eseguito? Le prestazioni sono un problema? Puoi dimostrare che le prestazioni della serializzazione sono il problema?

"Ho pensato di usare solo repr() ed eval(), ma c'è un modo semplice per farlo senza usare eval()?"

Niente di più semplice di repr and eval.

Cosa c'è di sbagliato in eval?

È il problema "qualcuno potrebbe inserire codice dannoso nel file in cui ho serializzato le mie liste"?

Chi - in particolare - troverà e modificherà questo file per inserire codice dannoso? Qualsiasi cosa tu faccia per proteggere questo (cioè, la crittografia) rimuove "semplice" da esso.

+0

Il problema con eval è: è necessario eseguire da soli l'errorhandling (ad esempio errori di battitura). –

+0

Quali errori ti aspetti? L'hai prodotto con repr. Cosa può succedere? –

+0

Perché questo importa ?: potrebbe fare la differenza tra essere in grado di memorizzarlo in un varchar o una colonna di testo Chi - in particolare - troverà e modificherà questo file per inserire codice dannoso ?: privilegio standard vulnerabilità di escalation. –

8

personalmente userò yaml. è alla pari con JSON per le dimensioni di codifica, ma può rappresentare alcune cose più complesse (ad esempio classi, strutture ricorsive) quando necessario.

In [1]: import yaml 
In [2]: x = [1, 2, 3, 'pants'] 
In [3]: print(yaml.dump(x)) 
[1, 2, 3, pants] 

In [4]: y = yaml.load('[1, 2, 3, pants]') 
In [5]: y 
Out[5]: [1, 2, 3, 'pants'] 
8

Forse non si sta usando il protocollo di destra:

>>> import pickle 
>>> a = range(1, 100) 
>>> len(pickle.dumps(a)) 
492 
>>> len(pickle.dumps(a, pickle.HIGHEST_PROTOCOL)) 
206 

vedere la documentazione per pickle data formats.

-1

Per fortuna esiste una soluzione che utilizza COMPRESSIONE e risolve il problema di relativo a qualsiasi oggetto Python arbitrario comprese nuove classi. Piuttosto che gestire in modo semplice le semplici tuple , è preferibile utilizzare uno strumento DRY.
Il codice sarà più nitido e prontamente refactored in situazioni future simili.

y_serial.py oggetti modulo :: magazzino Python con SQLite

"serializzazione + persistenza :: in poche righe di codice, comprimere e annotare Python oggetti in SQLite, poi recuperarli in ordine cronologico con parole chiave, senza alcuna SQL . Il più utile modulo "standard" per un database per memorizzare dati senza schema. "

http://yserial.sourceforge.net

[Se siete ancora interessati, perché non attacca quei tuple in un dizionario, quindi applicare y_serial al dizionario. Probabilmente alcun overhead svanirà a causa della compressione trasparente in background zlib.]

Per quanto riguarda la leggibilità, la documentazione fornisce anche dettagli sul motivo per cui cPickle è stato selezionato nel corso JSON.