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

## Quali tipi di dati possono essere convertiti?

Il modulo `pickle` è in grado di serializzare i seguenti [tipi di dati in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tipi-di-dati-in-python/):

- Valori booleani: “true”, “false” e “none”
- Numeri interi e numeri complessi
- Stringhe (normali e Unicode)
- Elenchi
- Set
- [Tuple](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tuple-in-python/)
- Cartelle che consistono esclusivamente di oggetti corrispondenti
- Funzioni
- [Classi](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/classi-in-python/)

## 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:

```python
import pickle
colori = ['Blu', 'Rosso', 'Giallo', 'Arancione']
```

Dopodiché apriamo un file di testo nel formato *.pkl* e usiamo pickle.dump() per salvarvi la nostra lista. A tale scopo utilizziamo questo codice:

```python
with open('file_colori.pkl', 'wb') as f:
	pickle.dump(colori, f)
```

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

```python
with open('file_colori.pkl', 'rb') as f:
	colori_deserializzati = pickle.load(f)
	print(colori_deserializzati)
```

Otteniamo così il seguente risultato:

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

## 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:

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

Nel codice seguente, quindi, creiamo un nuovo file, convertiamo i dati e poi li convertiamo di nuovo come test per serializzare questa cartella:

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

Il risultato sarà simile a questo:

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

Ora è possibile accedere alle informazioni come di consueto. Chiediamo il seguente output come esempio:

```python
# 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."
)
```

L’output si presenterà nel modo seguente:

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

## 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:

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

Dopo aver serializzato la classe e averla riconvertita nel suo formato originale, otteniamo questo risultato:

```python
Questo è l’oggetto serializzato:
b'\x80\x03c__main__\nEsempioClasse\nq\x00)\x81q\x01.'
Questo è un_dict dell’oggetto deserializzato:
{'colore': 'blu', 'numero': 3}
```

## 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](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/quale-linguaggio-di-programmazione-imparare/). Nell’esempio seguente, creiamo una stringa, la serializziamo e poi applichiamo il programma di compressione:

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

## 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](https://www.ionos.it/hosting/deploy-now "Deploy Now di IONOS") 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.


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/python-pickle/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/python-pickle/) for AI/LLM consumption.