Serializzazione Python: perché pickle?


87

Ho capito che il pickling Python è un modo per "memorizzare" un oggetto Python in un modo che rispetta la programmazione degli oggetti, diverso da un output scritto in file txt o DB.

Hai maggiori dettagli o riferimenti sui seguenti punti:

  • dove vengono "conservati" gli oggetti in salamoia?
  • perché il decapaggio preserva la rappresentazione degli oggetti più che, ad esempio, la memorizzazione in DB?
  • posso recuperare oggetti in salamoia da una sessione di shell Python a un'altra?
  • hai esempi significativi di quando la serializzazione è utile?
  • la serializzazione con pickle implica la "compressione" dei dati?

In altre parole, sto cercando un documento sul pickling: Python.doc spiega come implementare pickle ma sembra non immergersi nei dettagli sull'uso e sulla necessità della serializzazione.


Per salvare lo stato per un successivo ripristino o per condividere / copiare un oggetto in un diverso runtime Python sarebbe la mia ipotesi.
synthesizerpatel

13
Molte delle tue domande trovano risposta nell'articolo di Wikipedia sulla serializzazione: en.wikipedia.org/wiki/Serialization
NPE

5
stai chiedendo perché avrei bisogno di Pickle per la serializzazione in Python? o piuttosto qual è (lo scopo della) serializzazione dopo tutto? .
moooeeeep

Forse è utile menzionare i problemi di sicurezza con Pickle. Esempi possono essere trovati nei documenti e in numerose domande SO, come questa .
djvg

Risposte:


99

Pickling è un modo per convertire un oggetto Python (list, dict, ecc.) In un flusso di caratteri. L'idea è che questo flusso di caratteri contenga tutte le informazioni necessarie per ricostruire l'oggetto in un altro script Python.

Per quanto riguarda dove vengono memorizzate le informazioni in salamoia, di solito si farebbe:

with open('filename', 'wb') as f:
    var = {1 : 'a' , 2 : 'b'}
    pickle.dump(var, f)

Ciò memorizzerebbe la versione in salamoia del nostro vardict nel file "filename". Quindi, in un altro script, potresti caricare da questo file in una variabile e il dizionario verrebbe ricreato:

with open('filename','rb') as f:
    var = pickle.load(f)

Un altro uso per il decapaggio è se hai bisogno di trasmettere questo dizionario su una rete (magari con socket o qualcosa del genere). Devi prima convertirlo in un flusso di caratteri, quindi puoi inviarlo su una connessione socket.

Inoltre, non c'è "compressione" di cui parlare qui ... è solo un modo per convertire da una rappresentazione (in RAM) a un'altra (in "testo").

About.com ha una bella introduzione al decapaggio qui .


2
di solito si farebbewith open('filename') as f: ...
moooeeeep

3
Inoltre, dovresti farlo with open(filename, 'wb') as f: ...o non saresti in grado di scrivere sul file.
Tim Pietzcker

Grazie!! Questo sulla gestione della persistenza di Python è carino, qui
kiriloff

1
In generale non è una buona idea usare pickleper trasmettere un dizionario su una rete (json potrebbe essere migliore qui). Sebbene in rari casi potrebbe essere utile, ad esempio, multiprocessingmodule.
jfs

@Tim Pietzcker: protocol=0(predefinito su Python2.x) può essere utilizzato con i file aperti in modalità testo.
jfs

36

Il decapaggio è assolutamente necessario per il calcolo distribuito e parallelo.

Supponi di voler eseguire una riduzione della mappa parallela con multiprocessing(o attraverso i nodi del cluster con pyina ), quindi devi assicurarti che la funzione che desideri mappare tra le risorse parallele sia selezionata. Se non si sottrae, non puoi inviarlo ad altre risorse su un altro processo, computer, ecc. Vedi anche qui per un buon esempio.

Per fare ciò, uso dill , che può serializzare quasi tutto in Python. Dill ha anche alcuni buoni strumenti per aiutarti a capire cosa sta causando il fallimento del decapaggio quando il tuo codice fallisce.

E, sì, le persone usano il picking per salvare lo stato di un calcolo, o la tua sessione ipython , o qualsiasi altra cosa. Puoi anche estendere Pickler e UnPickler di pickle per eseguire la compressione con bz2o gzipse lo desideri.


0

Lo trovo particolarmente utile con classi personalizzate grandi e complesse. In un particolare esempio a cui sto pensando, "raccogliere" le informazioni (da un database) per creare la classe era già metà della battaglia. Quindi le informazioni memorizzate nella classe potrebbero essere modificate in fase di esecuzione dall'utente.

Potresti avere un altro gruppo di tabelle nel database e scrivere un'altra funzione per esaminare tutto ciò che è memorizzato e scriverlo nelle nuove tabelle del database. Quindi dovresti scrivere un'altra funzione per poter caricare qualcosa salvato leggendo di nuovo tutte quelle informazioni.

In alternativa, puoi mettere sottaceto l'intera classe così com'è e quindi memorizzarla in un singolo campo nel database. Quindi, quando vai a caricarlo di nuovo, verrà ricaricato tutto in una volta come era prima. Questo può finire per risparmiare molto tempo e codice durante il salvataggio e il recupero di classi complicate.


-1

è una specie di serializzazione. usa cPickle è molto più veloce di pickle.

import pickle
##make Pickle File
with open('pickles/corups.pickle', 'wb') as handle:
    pickle.dump(corpus, handle)

#read pickle file
with open('pickles/corups.pickle', 'rb') as handle:
    corpus = pickle.load(handle)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.