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.

Managed Nextcloud di IONOS Cloud
Lavora con il tuo team sul cloud
  • 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']
python

Dopodiché 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)
python

L’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)
python

Otteniamo così il seguente risultato:

['Blu', 'Rosso', 'Giallo', 'Arancione']
python

Serializzare 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"
	}
}
python

Nel 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)
python

Il 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"}
}
python

Ora è 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."
)
python

L’output si presenterà nel modo seguente:

La terza persona si chiama Lisa e ha 22 anni.
python

Convertire 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")
python

Dopo 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}
python

Comprimere 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)
python

Avvertenze 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.

Consiglio

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.

Hai trovato questo articolo utile?
Vai al menu principale