Python pickle: come serializzare gli oggetti
Con pickle
di Python è possibile serializzare e successivamente deserializzare oggetti. La conversione può essere effettuata con numerosi tipi di dati. Tuttavia, poiché in un file può essere memorizzato anche del codice maligno, è consigliabile convertire nel formato originale solo i file provenienti da fonti affidabili.
Cos’è pickle
di Python?
Il nome pickle
può suonare insolito, se si pensa che in inglese significa sottaceto. Tuttavia, una volta compreso il funzionamento e lo scopo del modulo, non è difficile capire il perché di questo nome. Python pickle
consente infatti di salvare gli oggetti per poterli utilizzare in un secondo momento, condividerli e usarli per un altro progetto. Per fare ciò, gli oggetti vengono convertiti in un formato salvabile: questa pratica è chiamata serializzazione. Questo processo può essere usato anche per deserializzare gli oggetti, cioè per riconvertirli nel loro formato originale. Python pickle
è particolarmente utile a chi desidera utilizzare frequentemente gli oggetti.
L’oggetto viene convertito in un flusso di byte, in cui tutte le informazioni vengono trasferite inalterate. Alla fine, l’oggetto può continuare a essere utilizzato anche dopo la conversione nel formato originale. Inoltre, Python pickle
fornisce istruzioni per una deserializzazione efficace, consentendo di ricostruire la struttura originale fin nei minimi dettagli. L’uso di Python pickle
fa risparmiare molto tempo, poiché gli oggetti creati una volta non devono essere ricreati per ogni utilizzo. Il formato di salvataggio è .pkl.
- Massima sicurezza dei tuoi dati
- Strumenti di collaborazione per lavorare in team
- Aggiornamenti automatici
Quali tipi di dati possono essere convertiti?
Il modulo pickle
è in grado di serializzare i seguenti tipi di dati in Python:
- Valori booleani: “true”, “false” e “none”
- Numeri interi e numeri complessi
- Stringhe (normali e Unicode)
- Elenchi
- Set
- Tuple
- Cartelle che consistono esclusivamente di oggetti corrispondenti
- Funzioni
- Classi
Quali sono i diversi metodi?
Il modulo pickle
mette a disposizione tre metodi di lavoro:
pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
: utilizzato per la serializzazione, crea un file con il risultato desiderato;pickle.dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
: altrettanto utilizzato per la serializzazione, ma restituisce una stringa di byte;pickle.load(file, *, fix_imports=True, encoding='ASCII', errors="strict", buffers=None)
: utilizzato per la deserializzazione, legge il file salvato a questo scopo;pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
: altrettanto utilizzato per la deserializzazione, ma opera con una stringa di byte.
Per distinguere i due metodi, basta ricordare che la “s” in pickle.dumps
e pickle.loads
sta per “stringa”.
Python pickle
: esempio di funzionamento
Per illustrare meglio il funzionamento di pickle
in Python, ci serviremo di un esempio facile. Creeremo una lista semplice contenente quattro colori. Il nostro codice è il seguente:
import pickle
colori = ['Blu', 'Rosso', 'Giallo', 'Arancione']
pythonDopodiché apriamo un file di testo nel formato .pkl e usiamo pickle.dump()
per salvarvi la nostra lista. A tale scopo utilizziamo questo codice:
with open('file_colori.pkl', 'wb') as f:
pickle.dump(colori, f)
pythonL’abbreviazione wb
indica al sistema di aprire il file in forma binaria. In questo modo i dati contenuti vengono visualizzati come oggetto byte. L’elenco dei “colori” viene quindi salvato in questo file con dump()
. Infine, il file viene chiuso automaticamente.
Convertire il file di memoria nel formato originale
Se ora desideri deserializzare nuovamente un file binario, puoi usare il metodo Python pickle.load()
. Con il codice seguente, converti l’oggetto nel suo formato originale e avvii un output. Aggiungiamo l’abbreviazione rb
, che sta per “read binary”.
with open('file_colori.pkl', 'rb') as f:
colori_deserializzati = pickle.load(f)
print(colori_deserializzati)
pythonOtteniamo così il seguente risultato:
['Blu', 'Rosso', 'Giallo', 'Arancione']
pythonSerializzare il dizionario con Python pickle
Con Python pickle
è anche possibile serializzare facilmente tipi di dati più complessi, come cartelle (directory), e poi riconvertirli nella loro forma originale. Per fare questo, creiamo prima una cartella con il nome “persone”. Qui memorizziamo alcuni dati diversi per persone diverse:
import pickle
persone = {
'Persona 1': {
'Nome': "Maria", 'Età': 56, 'Città': "Milano"
},
'Persona 2': {
'Nome': "Paolo", 'Età': 66, 'Città': "Milano"
},
'Persona 3': {
'Nome': "Lisa", 'Età': 22, 'Città': "Roma"
},
'Persona 4': {
'Nome': "Lara", 'Età': 34, 'Città': "Bologna"
}
}
pythonNel codice seguente, quindi, creiamo un nuovo file, convertiamo i dati e poi li convertiamo di nuovo come test per serializzare questa cartella:
with open("persone_dict.pkl", "wb") as f:
pickle.dump(persone, f)
with open("persone_dict.pkl", "rb") as f:
dict_deserializzato = pickle.load(f)
print(dict_deserializzato)
pythonIl risultato sarà simile a questo:
persone = {
'Persona 1': { 'Nome': "Maria", 'Età': 56, 'Città': "Milano"},
'Persona 2': { 'Nome': "Paolo", 'Età': 66, 'Città': "Milano"},
'Persona 3': { 'Nome': "Lisa", 'Età': 22, 'Città': "Roma"},
'Persona 4': { 'Nome': "Lara", 'Età': 34, 'Città': "Bologna"}
}
pythonOra è possibile accedere alle informazioni come di consueto. Chiediamo il seguente output come esempio:
# Definire il dizionario
dict_deserializzato = {
'Persona 1': {'Nome': "Maria", 'Età': 56, 'Città': "Milano"},
'Persona 2': {'Nome': "Paolo", 'Età': 66, 'Città': "Milano"},
'Persona 3': {'Nome': "Lisa", 'Età': 22, 'Città': "Roma"},
'Persona 4': {'Nome': "Lara", 'Età': 34, 'Città': "Bologna"}
}
# Stampa l'output
print(
"La terza persona si chiama "
+ dict_deserializzato["Persona 3"]["Nome"]
+ " e ha "
+ str(dict_deserializzato["Persona 3"]["Età"])
+ " anni."
)
pythonL’output si presenterà nel modo seguente:
La terza persona si chiama Lisa e ha 22 anni.
pythonConvertire una classe in una stringa
Nel prossimo esempio, utilizziamo Python pickle
per salvare una classe in una stringa. Questa classe contiene tipi di dati completamente diversi, ma che possono tutti essere presi in considerazione. Creiamo una classe chiamata “ExampleClass” e poi la serializziamo. Il codice per fare ciò è il seguente:
import pickle
class EsempioClasse:
def __init__(self):
self.a_number = 17
self.a_list = [5, 10, 15]
self.a_tuple = (18, 19)
self.a_string = "hallo"
self.a_dict = {"colore": "blu", "numero": 3}
oggetto_esempio = EsempioClasse()
oggetto_serializzato = pickle.dumps(oggetto_esempio)
print(f"Questo è l'oggetto serializzato:\n{oggetto_serializzato}\n")
oggetto_esempio.a_dict = None
oggetto_deserializzato = pickle.loads(oggetto_serializzato)
print(f"Questo è un_dict dell'oggetto deserializzato:\n{oggetto_deserializzato.a_dict}\n")
pythonDopo aver serializzato la classe e averla riconvertita nel suo formato originale, otteniamo questo risultato:
Questo è l’oggetto serializzato:
b'\x80\x03c__main__\nEsempioClasse\nq\x00)\x81q\x01.'
Questo è un_dict dell’oggetto deserializzato:
{'colore': 'blu', 'numero': 3}
pythonComprimere gli oggetti serializzati
In linea di principio, i file salvati con Python pickle
sono relativamente compatti. Tuttavia, è anche possibile e in alcuni casi consigliabile comprimere ulteriormente i file di memoria. Questo può essere fatto, per esempio, con il programma di compressione gratuito bzip2, che fa parte della libreria standard del linguaggio di programmazione. Nell’esempio seguente, creiamo una stringa, la serializziamo e poi applichiamo il programma di compressione:
import pickle
import bz2
stringaesempio = """Almost heaven, West Virginia
Blue Ridge Mountains, Shenandoah River
Life is old there, older than the trees
Younger than the mountains, growin' like a breeze
Country roads, take me home
To the place I belong
West Virginia, mountain mama
Take me home, country roads."""
serializzato = pickle.dumps(stringaesempio)
compresso = bz2.compress(serializzato)
pythonAvvertenze per lavorare con Python pickle
Anche se pickle
di Python è un metodo pratico ed efficace per convertire gli oggetti, lavorare con questo modulo comporta un grosso rischio: esiste la possibilità di trasportare codice maligno attraverso i dati serializzati. Sebbene questo non sia un problema con i propri dati, occorre prestare molta attenzione quando si lavora con file di terze parti. Per questo motivo, ti consigliamo di deserializzare sempre e solo file di memoria di cui conosci la fonte e di cui sai di poterti fidare.
Desideri distribuire app e siti direttamente con GitHub? Nulla di più facile, con Deploy Now di IONOS. Scegli la soluzione più adatta alle tue esigenze tra i diversi pacchetti disponibili e approfitta delle pratiche funzioni di rilevamento automatico del framework e di una configurazione rapida.