2011-09-21 5 views
34

Recentemente ho ricevuto un compito in cui ho bisogno di mettere un dizionario (in cui ogni chiave si riferisce a un elenco) in forma decapata. L'unico problema è che non ho idea di cosa sia la forma decapata. Qualcuno potrebbe indicarmi la direzione giusta di alcune buone risorse per aiutarmi ad imparare questo concetto? Grazie!Informazioni sul decapaggio in Python

+34

http://docs.python.org/library/pickle.html è il primo risultato di Google per "sottaceto", anche battendo la pagina di Wikipedia per la verdura conservata. – geoffspear

+17

@Wooble: so che è completamente fuori tema, ma la ricerca su Google varia a seconda della posizione, della cronologia delle ricerche e persino della cronologia di email/chat;). Ma sì, +1 per indicare i documenti. – 0xc0de

+6

@ 0xc0de Destra. Per me l'entrata principale * è * la verdura conservata. :-) Suppongo che dovrei iniziare a scrivere di più. –

risposta

17

Mentre altri hanno fatto notare alla documentazione Python sul modulo pickle, che è una grande risorsa, è anche possibile controlla Chapter 13: Serializing Python Objects di Dive Into Python 3 di Mark Pilgrim.

+0

Grazie per indicare una risorsa che spiega * perché * vorresti mettere sottaceti un oggetto python. –

3

http://docs.python.org/library/pickle.html#example

import pickle 

data1 = {'a': [1, 2.0, 3, 4+6j], 
     'b': ('string', u'Unicode string'), 
     'c': None} 

selfref_list = [1, 2, 3] 
selfref_list.append(selfref_list) 

output = open('data.pkl', 'wb') 

# Pickle dictionary using protocol 0. 
pickle.dump(data1, output) 

# Pickle the list using the highest protocol available. 
pickle.dump(selfref_list, output, -1) 

output.close() 
66

Il modulo pickle implementa un algoritmo fondamentale, ma potente per la serializzazione e deserializzare una struttura di oggetti Python.

Decapaggio - è il processo in cui una gerarchia di oggetti Python viene convertito in un flusso di byte, e deserializzare - è l'operazione inversa, per cui un flusso di byte viene riconvertito in una gerarchia di oggetti.

decapaggio (e unpickling) è alternativamente noti come serializzazione, smistamento, o appiattimento.

import pickle 

data1 = {'a': [1, 2.0, 3, 4+6j], 
     'b': ('string', u'Unicode string'), 
     'c': None} 

selfref_list = [1, 2, 3] 
selfref_list.append(selfref_list) 

output = open('data.pkl', 'wb') 

# Pickle dictionary using protocol 0. 
pickle.dump(data1, output) 

# Pickle the list using the highest protocol available. 
pickle.dump(selfref_list, output, -1) 

output.close() 

Per leggere da un file in salamoia -

import pprint, pickle 

pkl_file = open('data.pkl', 'rb') 

data1 = pickle.load(pkl_file) 
pprint.pprint(data1) 

data2 = pickle.load(pkl_file) 
pprint.pprint(data2) 

pkl_file.close() 

fonte - https://docs.python.org/2/library/pickle.html

+8

Questo è semplicemente uno dei migliori esempi di codice che abbia mai visto. Splendidamente formattato e meravigliosamente succinto. Grazie. – anon58192932

+1

Non ho capito perché 'data1 = pickle.load (pkl_file)' non ha caricato il file completo (data.pkl)? – Naive

+0

Il decapaggio richiede un parametro di output del file? Come fai a mantenere l'oggetto serializzato per memorizzarlo altrove? – Praxiteles

3

Pickling in Python viene utilizzato per serializzare e de-serializzare oggetti Python, come un dizionario nel tuo caso. Di solito uso il modulo cPickle in quanto può essere molto più veloce del modulo Pickle.

import cPickle as pickle  

def serializeObject(pythonObj): 
    return pickle.dumps(pythonObj, pickle.HIGHEST_PROTOCOL) 

def deSerializeObject(pickledObj): 
    return pickle.loads(pickledObj) 
19

decapaggio è un mini-linguaggio che può essere utilizzato per convertire lo stato rilevante da un oggetto Python in una stringa, dove questa stringa rappresenta univoco l'oggetto. Quindi (un) il decapaggio può essere usato per convertire la stringa in un oggetto dal vivo, "ricostruendo" l'oggetto dallo stato salvato che ha fondato la stringa.

>>> import pickle 
>>> 
>>> class Foo(object): 
... y = 1 
... def __init__(self, x): 
...  self.x = x 
...  return 
... def bar(self, y): 
...  return self.x + y 
... def baz(self, y): 
...  Foo.y = y 
...  return self.bar(y) 
... 
>>> f = Foo(2) 
>>> f.baz(3) 
5 
>>> f.y 
3 
>>> pickle.dumps(f) 
"ccopy_reg\n_reconstructor\np0\n(c__main__\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI2\nsb." 

Che cosa si può vedere qui è che salamoia non salva il codice sorgente per la classe, ma non memorizzare un riferimento alla definizione di classe. Fondamentalmente, puoi quasi leggere la stringa scelta ... dice (approssimativamente tradotto) "call copy_reg's reconstructor dove gli argomenti sono la classe definita da __main__.Foo e poi fanno altre cose". L'altra roba è lo stato salvato dell'istanza. Se si guarda più in profondità, è possibile estrarre che "stringa x" è impostata su "l'intero 2" (circa: S'x'\np6\nI2). Questa è in realtà una parte troncata della stringa decapitata per una voce del dizionario ... il dict è f.__dict__, ovvero {'x': 2}. Se si guarda il codice sorgente per pickle, fornisce molto chiaramente una traduzione per ogni tipo di oggetto e operazione da python a codice byte decapitato.

Si noti inoltre che esistono diverse varianti del linguaggio di decapaggio. Il valore predefinito è il protocollo 0, che è più leggibile. C'è anche il protocollo 2, mostrato di seguito (e 1,3 e 4, a seconda della versione di Python che si sta utilizzando).

>>> pickle.dumps([1,2,3]) 
'(lp0\nI1\naI2\naI3\na.' 
>>> 
>>> pickle.dumps([1,2,3], -1) 
'\x80\x02]q\x00(K\x01K\x02K\x03e.' 

Anche in questo caso, è ancora un dialetto della lingua decapaggio, e si può vedere che la stringa protocollo 0 dice "ottenere una lista, includere I1, I2, I3", mentre il protocollo 2 è più difficile da leggere, ma dice la stessa cosa Il primo bit \x80\x02 indica che è il protocollo 2 - quindi hai ] che dice che è un elenco, quindi di nuovo puoi vedere i numeri interi 1,2,3. Ancora una volta, controlla il codice sorgente di pickle per vedere la mappatura esatta per la lingua di decapaggio.

Per invertire il decapaggio su una stringa, utilizzare carico/carichi.

>>> p = pickle.dumps([1,2,3]) 
>>> pickle.loads(p) 
[1, 2, 3] 
+2

Come principiante, stavo avendo questa domanda nella mia testa, che tipo di cose che pickle fa dentro? Questa risposta è stata affrontata più di altre. –

2

Il modulo pickle implementa un algoritmo fondamentale, ma potente per la serializzazione e deserializzare una struttura di oggetti Python. "Pickling" è il processo mediante il quale una gerarchia di oggetti Python viene convertita in un flusso di byte e "deselezionare" è l'operazione inversa, in base alla quale un flusso di byte viene riconvertito in una gerarchia di oggetti. Il decapaggio (e il disfacimento) è alternativamente noto come "serializzazione", "marshalling" o "appiattimento", tuttavia, per evitare confusione, i termini usati qui sono "decapaggio" e "disimpegno".

Il modulo pickle ha un cugino ottimizzato chiamato modulo cPickle. Come suggerisce il nome, cPickle è scritto in C, quindi può essere fino a 1000 volte più veloce di pickle. Tuttavia, non supporta la sottoclasse delle classi Pickler() e Unpickler(), perché in cPickle queste sono funzioni, non classi. La maggior parte delle applicazioni non ha bisogno di questa funzionalità e può beneficiare delle migliori prestazioni di cPickle. Oltre a ciò, le interfacce dei due moduli sono quasi identiche; l'interfaccia comune è descritta in questo manuale e le differenze vengono evidenziate dove necessario. Nelle seguenti discussioni, usiamo il termine "pickle" per descrivere collettivamente i moduli pickle e cPickle.

I flussi di dati dei due moduli prodotti sono garantiti per essere intercambiabili.

+0

Assicurarsi di aprire sempre i file pickle creati con i protocolli> = 1 in modalità binaria. Per il vecchio protocollo pickle basato su ASCII 0 è possibile utilizzare la modalità testo o la modalità binaria finché si rimane coerenti. Un file pickle scritto con il protocollo 0 in modalità binaria conterrà linefeed solitari come terminatori di riga e quindi sembrerà "divertente" se visualizzato in Blocco note o altri editor che non supportano questo formato. – Naren

+1

cpickle viene convertito in _pickle in python 3 – Naren

+0

cpickle è molto più veloce di pickle perché, come suggerisce il nome, è scritto in linguaggio c. – Naren