Python Language
Serializzazione dei dati sottaceti
Ricerca…
Sintassi
pickle.dump (oggetto, file, protocollo) # Per serializzare un oggetto
pickle.load (file) # Per de-serializzare un oggetto
pickle.dumps (object, protocol) # Per serializzare un oggetto in byte
pickle.loads (buffer) # Per deserializzare un oggetto da byte
Parametri
Parametro | Dettagli |
---|---|
oggetto | L'oggetto che deve essere memorizzato |
file | Il file aperto che conterrà l'oggetto |
protocollo | Il protocollo utilizzato per il decapaggio dell'oggetto (parametro opzionale) |
buffer | Un oggetto byte che contiene un oggetto serializzato |
Osservazioni
Tipi pickleable
I seguenti oggetti sono selezionabili.
-
None
,True
eFalse
- numeri (di tutti i tipi)
- archi (di tutti i tipi)
-
tuple
s,list
s,set
s edict
s contenenti solo oggetti selezionabili - funzioni definite al livello più alto di un modulo
- funzioni integrate
- classi che sono definite al livello più alto di un modulo
- istanze di tali classi il cui
__dict__
o il risultato della chiamata__getstate__()
è selezionabile (vedere i documenti ufficiali per i dettagli).
- istanze di tali classi il cui
Basato sulla documentazione ufficiale di Python .
pickle
e sicurezza
Il modulo pickle non è sicuro . Non dovrebbe essere usato quando si ricevono i dati serializzati da una parte non fidata, come su Internet.
Usare Pickle per serializzare e deserializzare un oggetto
Il modulo pickle
implementa un algoritmo per trasformare un oggetto Python arbitrario in una serie di byte. Questo processo è anche chiamato serializzare l'oggetto. Il flusso di byte che rappresenta l'oggetto può quindi essere trasmesso o memorizzato e successivamente ricostruito per creare un nuovo oggetto con le stesse caratteristiche.
Per il codice più semplice, utilizziamo le funzioni dump()
e load()
.
Per serializzare l'oggetto
import pickle
# An arbitrary collection of objects supported by pickle.
data = {
'a': [1, 2.0, 3, 4+6j],
'b': ("character string", b"byte string"),
'c': {None, True, False}
}
with open('data.pickle', 'wb') as f:
# Pickle the 'data' dictionary using the highest protocol available.
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
Per deserializzare l'oggetto
import pickle
with open('data.pickle', 'rb') as f:
# The protocol version used is detected automatically, so we do not
# have to specify it.
data = pickle.load(f)
Usando oggetti pickle e byte
È anche possibile serializzare e deserializzare in su oggetti byte, utilizzando le dumps
e loads
funzione, che sono equivalenti a dump
e load
.
serialized_data = pickle.dumps(data, pickle.HIGHEST_PROTOCOL)
# type(serialized_data) is bytes
deserialized_data = pickle.loads(serialized_data)
# deserialized_data == data
Personalizza dati sottodimensionati
Alcuni dati non possono essere decapitati. Altri dati non dovrebbero essere messi in salamoia per altri motivi.
Ciò che verrà sottoposto a __getstate__
può essere definito nel metodo __getstate__
. Questo metodo deve restituire qualcosa che è selezionabile.
Sul lato opposto è __setstate__
: riceverà ciò che __getstate__
creato e deve inizializzare l'oggetto.
class A(object):
def __init__(self, important_data):
self.important_data = important_data
# Add data which cannot be pickled:
self.func = lambda: 7
# Add data which should never be pickled, because it expires quickly:
self.is_up_to_date = False
def __getstate__(self):
return [self.important_data] # only this is needed
def __setstate__(self, state):
self.important_data = state[0]
self.func = lambda: 7 # just some hard-coded unpicklable function
self.is_up_to_date = False # even if it was before pickling
Ora, questo può essere fatto:
>>> a1 = A('very important')
>>>
>>> s = pickle.dumps(a1) # calls a1.__getstate__()
>>>
>>> a2 = pickle.loads(s) # calls a1.__setstate__(['very important'])
>>> a2
<__main__.A object at 0x0000000002742470>
>>> a2.important_data
'very important'
>>> a2.func()
7
L'implementazione qui pikles una lista con un valore: [self.important_data]
. Questo era solo un esempio, __getstate__
potrebbe aver restituito tutto ciò che è picklable, a condizione che __setstate__
sappia come fare il referendum. Una buona alternativa è un dizionario di tutti i valori: {'important_data': self.important_data}
.
Il costruttore non viene chiamato! Si noti che nell'istanza dell'esempio precedente a2
stato creato in pickle.loads
senza mai chiamare A.__init__
, quindi A.__setstate__
doveva inizializzare tutto ciò che __init__
avrebbe inizializzato se fosse stato chiamato.