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,TrueeFalse - numeri (di tutti i tipi)
- archi (di tutti i tipi)
-
tuples,lists,sets edicts 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.