Articolo originale: https://www.freecodecamp.org/news/python-read-json-file-how-to-load-json-from-a-file-and-parse-dumps/

Se vuoi imparare a lavorare con i file JSON in Python, allora questo articolo fa per te.

Imparerai:

  • Perché il formato JSON è così importante.
  • La sua struttura base e i tipi di dato.
  • Come JSON e i dizionari Python lavorano insieme in Python.
  • Come lavorare con il modulo integrato di Python json.
  • Come convertire le stringhe JSON in oggetti Python e viceversa.
  • Come usare loads() e dumps()
  • Come indentare le stringhe JSON automaticamente.
  • Come leggere i file JSON in Python usando load()
  • Come scrivere file JSON in Python usando dump()
  • E altro ancora!

Pronto? Iniziamo! ✨

🔹 Introduzione: cos'è JSON?

image-98

Il formato JSON era originariamente ispirato alla sintassi di JavaScript (un linguaggio di programmazione usato per lo sviluppo web). In seguito, è diventato un formato dati indipendente dal linguaggio e la maggior parte dei linguaggi di programmazione usati oggi possono generare e leggere JSON.

Importanza e Casi di Utilizzo di JSON

JSON è fondamentalmente un formato utilizzato per memorizzare o rappresentare i dati. I suoi casi d'uso comuni includono lo sviluppo web e i file di configurazione.

Vediamo perché:

  • Sviluppo Web: JSON è comunemente usato nelle applicazioni web per inviare dati dal server al client e viceversa.
image-65
  • File di configurazione: JSON viene anche utilizzato per memorizzare configurazioni e impostazioni. Ad esempio, per creare una App Google Chrome, è necessario includere un file JSON chiamato manifest.json per specificare il nome dell'app, la sua descrizione, la versione corrente e altre proprietà e impostazioni.
image-99

🔸 Struttura e Formato di JSON

Ora che sai per cosa viene usato il formato JSON, esaminiamo la sua struttura base con un esempio che rappresenta i dati dell'ordinazione di una pizza:

{ 
	"taglia": "media",
	"prezzo": 15.67,
	"condimenti": ["funghi", "salame", "basilico"],
	"formaggio_extra": false,
	"consegna": true,
	"cliente": {
		"nome": "Jane Doe",
		"telefono": null,
		"email": "janedoe@email.com"
	}
}
Esempio di file .json

Queste sono le caratteristiche principali del formato JSON:

  • C'è una sequenza di coppie chiave-valore racchiusa tra parentesi graffe {}.
  • Ogni chiave viene associata a un particolare valore usando questo formato:
"chiave": <valore> 

💡 Suggerimento: i valori che richiedono l'uso delle virgolette devono essere racchiusi tra virgolette doppie.

  • Le coppie chiave-valore sono separate da una virgola. Solo l'ultima coppia non è seguita da una virgola.
{
	"taglia": "media", # Virgola!
	"prezzo": 15.67
}

💡 Suggerimento: tipicamente JSON viene formattato con diversi livelli di indentazione per facilitare la lettura dei dati. In questo articolo imparerai come aggiungere automaticamente l'indentazione con Python.

Tipi di Dato JSON: Chiavi e Valori

I file JSON hanno regole specifiche che determinano quali tipi di dato sono validi per chiavi e valori.

  • Le chiavi devono essere stringhe.
  • I valori possono essere stringhe, numeri, array, valori booleani (true/ false), null, oppure un oggetto JSON.

Secondo la documentazione di Python:

Le chiavi nelle coppie chiave-valore di JSON sono sempre di tipo str. Quando un dizionario viene convertito in JSON, tutte le chiavi del dizionario sono forzate come stringhe.

Guida di Stile

Secondo la Guida di Stile JSON di Google:

  • Scegli sempre nomi significativi.
  • Il tipo array dovrebbe avere il nome della chiave al plurale. Tutti gli altri nomi di chiave dovrebbero essere al singolare. Ad esempio usare "ordinazioni" invece di "ordinazione" se il valore corrispondente è un array.
  • Non ci dovrebbero essere commenti in oggetti JSON.

🔹 JSON vs Dizionari Python

JSON e i dizionari potrebbero sembrare sulle prime molto simili (visivamente), ma in realtà sono piuttosto diversi. Vediamo come sono "connessi" e come si completano a vicenda rendendo Python un potente strumento per lavorare con i file JSON.

JSON è un formato di file utilizzato per rappresentare e conservare dati mentre un dizionario Python è l'effettiva struttura dati (oggetto) che viene mantenuta in memoria mentre un programma Python è in esecuzione.

Come Lavorano Insieme JSON e i Dizionari Python

image-100

Quando lavoriamo con i file JSON in Python, non è possibile semplicemente leggerli e utilizzarne direttamente i dati in un programma. Questo perché l'intero file sarebbe rappresentato come una singola stringa e non sarebbe possibile accedere singolarmente alle coppie di chiave-valore.

A meno che...

Non usiamo le coppie di chiave-valore del file JSON per creare un dizionario Python da poter utilizzare in un programma per leggere i dati, utilizzarli e modificarli (se necessario).

Questa è la connessione principale tra JSON e i dizionari Python. JSON è la rappresentazione stringa dei dati e i dizionari sono l'effettiva struttura dati in memoria creata quando il programma è in esecuzione.

Ora che conosciamo di più il formato JSON, immergiamoci negli aspetti pratici che riguardano l'utilizzo di JSON in Python.

🔸 Il Modulo JSON

Fortunatamente, Python è dotato di un modulo incorporato chiamato json. È installato automaticamente quando si installa Python e include funzioni per aiutare a lavorare con file JSON e stringhe.

Useremo questo modulo negli esempi che seguono.

Come Importare il Modulo JSON

Per usare json in un programma, occorre scrivere un'istruzione di importazione all'inizio del file.

In questo modo:

image-73

Con questa riga, avremo l'accesso alle funzioni definite nel modulo. Ne useremo svariate negli esempi.

💡 Suggerimento: se scrivi questa istruzione di importazione dovrai usare questa sintassi per chiamare una funzione definita nel modulo json:

json

🔹 Python e le Stringhe JSON

Per illustrare come lavorano alcune delle funzioni più importanti del modulo json, utilizzeremo una stringa multi-riga con formato JSON.

Stringa JSON

In particolare, useremo questa stringa negli esempi. È semplicemente una normale stringa Python multi-riga che segue il formato JSON.

dati_JSON =  """
{
	"taglia": "Media",
	"prezzo": 15.67,
	"condimenti": ["Funghi", "Pecorino", "Salame", "Basilico"],
	"cliente": {
		"nome": "Jane Doe",
		"telefono": "455-344-234",
		"email": "janedoe@email.com"
	}
}
"""
Stringa JSON
  • Per definire una stringa multi-riga in Python usiamo le virgolette triple.
  • Poi assegniamo la stringa alla variabile dati_JSON.

💡 Suggerimento: La Guida di Stile di Python raccomanda l'uso delle virgolette doppie per le stringhe racchiuse tra virgolette triple.

Da Stringa JSON a Dizionario Python

Useremo una stringa con il formato JSON per creare un dizionario Python, in modo da potervi accedere e lavorare apportando modifiche.

Per fare questo useremo la funzione loads() del modulo json, passando la stringa come argomento.

Questa è la sintassi:

json_1

Ecco il codice:

# Importazione del modulo
import json

# Stringa con formato JSON
dati_JSON =  """
{
	"taglia": "Media",
	"prezzo": 15.67,
	"condimenti": ["Funghi", "Pecorino", "Salame", "Basilico"],
	"cliente": {
		"nome": "Jane Doe",
		"telefono": "455-344-234",
		"email": "janedoe@email.com"
	}
}
"""

# Converte una stringa JSON in un dizionario
dati_diz = json.loads(dati_JSON)

Concentriamoci su questa riga:

dati_diz = json.loads(dati_JSON)
  • json.loads(dati_JSON) crea un nuovo dizionario con le coppie chiave-valore della stringa JSON e lo restituisce.
  • Successivamente il dizionario restituito viene assegnato alla variabile dati_diz.

Se stampiamo il nuovo dizionario otterremo questo risultato:

{'taglia': 'Media', 'prezzo': 15.67, 'condimenti': ['Funghi', 'Pecorino', 'Salame', 'Basilico'], 'cliente': {'nome': 'Jane Doe', 'telefono': '455-344-234', 'email': 'janedoe@email.com'}}

Il dizionario è stato popolato con i dati della stringa JSON. Ogni coppia chiave-valore è stata aggiunta con successo.

Ora vediamo cosa accade cercando di accedere ai valori delle coppie chiave-valore con la stessa sintassi usata per accedere ai valori di un normale dizionario Python:

print(dati_diz["taglia"])
print(dati_diz["prezzo"])
print(dati_diz["condimenti"])
print(dati_diz["cliente"])

Il risultato è:

Media
15.67
['Funghi', 'Pecorino', 'Salame', 'Basilico']
{'nome': 'Jane Doe', 'telefono': '455-344-234', 'email': 'janedoe@email.com'}

Esattamente quello che ci aspettavamo. Ogni chiave può essere usata per accedere al suo corrispondente valore.

💡 Suggerimento: è possibile usare questo dizionario come un qualsiasi altro dizionario Python. Ad esempio, si possono chiamare metodi di dizionario, aggiungere, aggiornare e rimuovere coppie chiave-valore e altro. È anche possibile usarlo in un loop for.

Da JSON a Python: Conversione di Tipo

Usando loads() per creare un dizionario Python da una stringa JSON noterai che alcuni valori verranno convertiti nei loro corrispondenti valori e tipi di dato Python.

Questa tabella presentata nella Documentazione Python per il modulo json riassume la corrispondenza tra i valori e tipi di dato JSON e Python:

image-5
Tabella presente nella documentazione ufficiale del modulo json

💡 Suggerimento: la stessa tabella di conversione si applica quando si lavora con file JSON.

Da Dizionari Python a Stringhe JSON

Ora sai come creare un dizionario Python da una stringa in formato JSON.

Ma delle volte potrebbe essere necessario fare esattamente l'opposto, creando una stringa in formato JSON da un oggetto (ad esempio un dizionario) per stamparlo, visualizzarlo, salvarlo o lavorarci come con una stringa.

Per fare questo possiamo usare la funzione dumps del modulo json passando l'oggetto come argomento:

json_2

💡 Suggerimento: questa funzione restituirà una stringa.

Questo è un esempio in cui il dizionario Python cliente viene convertito in una stringa in formato JSON e memorizzata in una variabile:

# Dizionario Python
cliente = {
    "nome": "Nora",
    "età": 56,
    "id": "45355",
    "colore_occhi": "verde",
    "indossa_occhiali": False
}

# Ottiene una stringa JSON formattata
cliente_JSON = json.dumps(cliente)

Focalizziamoci su questa riga:

cliente_JSON = json.dumps(cliente)
  • json.dumps(cliente) crea e restituisce una stringa con tutte le coppie chiave-valore del dizionario in formato JSON.
  • Successivamente la stringa viene assegnata alla variabile cliente_JSON.

Se stampiamo questa stringa otterremo questo risultato:

{"nome": "Nora", "età": 56, "id": "45355", "colore_occhi": "verde", "indossa_occhiali": false}

💡 Suggerimento: nota che l'ultimo valore (false) è stato cambiato. Nel dizionario Python questo valore era False, ma in JSON il valore equivalente è false. Questo permette di confermare che, in effetti, il dizionario originale è ora rappresentato come una stringa con il formato JSON.

Verificando il tipo di dato di questa variabile vedremo:

<class 'str'>

Quindi il valore restituito da questa funzione è sicuramente una stringa.

Da Python a JSON: Conversione di Tipo

Si verifica un processo di conversione di tipo anche quando si converte un dizionario in una stringa JSON. Questa tabella, tratta dalla Documentazione Python, illustra i valori corrispondenti:

image-6
Tabella dalla documentazione ufficiale del modulo json

Come Stampare JSON con Indentazione

Se usiamo la funzione dumps e stampiamo la stringa ottenuta nell'esempio precedente vedremo:

{"nome": "Nora", "età": 56, "id": "45355", "colore_occhi": "verde", "indossa_occhiali": false}

Non molto leggibile, vero?

È possibile migliorare la leggibilità di una stringa JSON aggiungendo l'indentazione.

Per farlo automaticamente è sufficiente passare un secondo argomento per specificare il numero di spazi da usare per indentare la stringa JSON:

json_3-1

💡 Suggerimento: il secondo argomento deve essere un intero non negativo (il numero di spazi) o una stringa. Se indent è una stringa (tipo "\t"), essa viene usata per indentare ciascun livello (fonte).

Ora se chiamiamo dumps con il secondo argomento:

cliente_JSON = json.dumps(cliente, indent=4)

Il risultato della stampa di cliente_JSON è:

{
    "nome": "Nora",
    "età": 56,
    "id": "45355",
    "colore_occhi": "verde",
    "indossa_occhiali": false
}

Fantastico, non è vero? Ora la stringa è ben formattata. Sarà molto utile per lavorare con i file e salvare i dati in un formato leggibile.

Come Ordinare le Chiavi

Le chiavi si possono anche ordinare alfabeticamente, se necessario. Per fare questo occorre utilizzare l'argomento sort_keys passando il valore True:

json_4-2

💡 Suggerimento: il valore di  sort_keys è False nella modalità predefinita, se non si passa un valore.

Ad esempio:

cliente_JSON = json.dumps(cliente, sort_keys=True)

Restituisce questa stringa con le chiavi ordinate alfabeticamente:

{"colore_occhi": "verde", "età": 56, "id": "45355", "indossa_occhiali": false, "nome": "Nora"}

Come Ordinare Alfabeticamente e Indentare (allo stesso tempo)

Per generare una stringa JSON che sia ordinata alfabeticamente e indentata occorre passare i due argomenti:

image-104

In questo caso il risultato è:

{
    "colore_occhi": "verde",
    "età": 56,
    "id": "45355",
    "indossa_occhiali": false,
    "nome": "Nora"
}

💡 Suggerimento: si possono passare questi argomenti in qualsiasi ordine, ma l'oggetto deve essere il primo argomento nella funzione.

Ora che sai come lavorare con le stringhe JSON, vedremo come è possibile lavorare con file JSON in un programma Python.

🔸 JSON e i File

JSON è tipicamente usato per conservare dati in dei file, quindi Python fornisce gli strumenti necessari per leggere questi tipi di file in un programma, per lavorare con i dati e scriverne nuovi.

💡 Suggerimento: un file JSON ha una estensione  .json:

image-62

Ora vediamo come è possibile lavorare con file .json in Python.

Come Leggere un File JSON in Python

Ipotizziamo di aver creato un file  ordinazioni.json con i dati che rappresentano due ordinazioni di una pizzeria:

{
	"ordinazioni": [ 
		{
			"taglia": "media",
			"prezzo": 15.67,
			"condimenti": ["funghi", "salame", "basilico"],
			"formaggio_extra": false,
			"consegna": true,
			"cliente": {
				"nome": "Jane Doe",
				"telefono": null,
				"email": "janedoe@email.com"
			}
		},
		{
			"taglia": "piccola",
			"prezzo": 6.54,
			"condimenti": null,
			"formaggio_extra": true,
			"consegna": false,
			"cliente": {
				"nome": "Foo Jones",
				"telefono": "556-342-452",
				"email": null
			}
		}
	]
}
ordinazioni.json

Prendiamoci un momento per analizzare la struttura di questo file JSON.

Ecco alcuni veloci suggerimenti:

  • Nota il tipo di dato dei valori, l'indentazione e la struttura generale del file.
  • Il valore della chiave principale "ordinazioni" è un array di oggetti JSON (questo array verrà rappresentato come una lista in Python). Ogni oggetto JSON contiene i dati dell'ordinazione di una pizza.

Se vogliamo leggere questo file in Python occorre semplicemente usare un'istruzione with:

json_5

💡 Suggerimento: nella sintassi qui sopra, si può assegnare a file (riquadro verde) un qualsiasi nome. Si tratta di una variabile che possiamo usare all'interno del blocco with per fare riferimento all'oggetto file.

La riga di codice chiave in questa sintassi è:

data = json.load(file)
  • json.load(file) crea e restituisce un nuovo dizionario Python con le coppie chiave-valore del file JSON.
  • Successivamente il dizionario viene assegnato alla variabile data .

💡 Suggerimento: nota che stiamo usando load() invece di loads(). Questa è una funzione diversa nel modulo json. Alla fine di questo articolo, saprai di più sulle differenze tra loro.

Una volta che abbiamo il contenuto del file JSON memorizzato nella variabile data come dizionario, è possibile usarlo per fare praticamente tutto quello che desideriamo.

Esempi

Per esempio, se scriviamo:

print(len(data["ordinazioni"]))

Il risultato sarà 2 perché il valore della chiave principale "ordinazioni" è una lista con due elementi.

È possibile anche usare le chiavi per accedere ai valori corrispondenti. Questo è ciò che si fa tipicamente quando si lavora con file JSON.

Ad esempio, per accedere ai condimenti del primo ordine, scriveremo:

data["ordinazioni"][0]["condimenti"]
  • Prima selezioniamo la chiave principale "ordinazioni".
  • Poi selezioniamo il primo elemento nella lista (indice 0).
  • Infine selezioniamo il valore che corrisponde alla chiave "condimenti".

Se stampiamo questo valore il risultato sarà:

['funghi', 'salame', 'basilico']

Proprio quello che ci aspettavamo. Dobbiamo semplicemente addentrarci più a fondo nella struttura del dizionario usando le chiavi e gli indici necessari. Si può usare il file o la stringa originale JSON come riferimento visivo. In questo modo è possibile accedere, modificare o eliminare qualunque valore.

💡 Suggerimento: tieni a mente che stiamo lavorando con il nuovo dizionario. Le modifiche fatte al dizionario non hanno effetto sul file JSON. Per aggiornare il contenuto del file occorre scrivere su quel file.

Come Scrivere su un File JSON

Ora, vediamo come si può scrivere su un file JSON.

La prima riga dell'istruzione with è molto simile. L'unica differenza è che occorre aprire il file in modalità di scrittura 'w' (write) per poter modificare il file.

json_6

💡 Suggerimento: se il file non esiste già nella directory di lavoro corrente, verrà creato automaticamente. Usando la modalità 'w' l'intero contenuto del file, se già esiste, verrà sovrascritto.

Ci sono due alternative per scrivere su un file JSON nel corpo di una istruzione with:

  • dump
  • dumps

La funzione dump() riceve due argomenti:

  • L'oggetto che verrà salvato in formato JSON (ad esempio un dizionario).
  • Il nome del file con cui verrà salvato (un oggetto file).
json_7

Ipotizziamo che la pizzeria voglia eliminare i dati dei clienti dal file JSON e voglia creare un nuovo file JSON chiamato ordinazioni_nuovo.json con questa nuova versione.

È possibile farlo con questo codice:

# Apre il file orders.json
with open("ordinazioni.json") as file:
    # Carica il suo contenuto e crea un nuovo dizionario
    data = json.load(file)

    # Cancella la coppia chiave-valore "cliente" da ciascun ordine
    for ordinazione in data["ordinazioni"]:
        del ordinazione["cliente"]

# Apre (o crea) un file ordinazioni_nuovo.json 
# e salva la nuova versione dei dati.
with open("ordinazioni_nuovo.json", 'w') as file:
    json.dump(data, file)

Questa era la versione originale dei dati nel file ordinazioni.json. Nota che esiste la coppia chiave-valore "cliente".

{
	"ordinazioni": [ 
		{
			"taglia": "media",
			"prezzo": 15.67,
			"condimenti": ["funghi", "salame", "basilico"],
			"formaggio_extra": false,
			"consegna": true,
			"cliente": {
				"nome": "Jane Doe",
				"telefono": null,
				"email": "janedoe@email.com"
			}
		},
		{
			"taglia": "piccola",
			"prezzo": 6.54,
			"condimenti": null,
			"formaggio_extra": true,
			"consegna": false,
			"cliente": {
				"nome": "Foo Jones",
				"telefono": "556-342-452",
				"email": null
			}
		}
	]
}
ordinazioni.json

Questa è la nuova versione nel file ordinazioni_nuovo.json:

{"ordinazioni": [{"taglia": "media", "prezzo": 15.67, "condimenti": ["funghi", "salame", "basilico"], "formaggio_extra": false, "consegna": true}, {"taglia": "piccola", "prezzo": 6.54, "condimenti": null, "formaggio_extra": true, "consegna": false}]}
ordinazioni_nuovo.json

Analizzando con cura il contenuto puoi vedere che la coppia chiave-valore "cliente" è stata rimossa da tutti gli ordini.

Tuttavia qualcosa manca nel file, giusto?

Riflettiamoci per un attimo... Cosa potrebbe essere?

L'indentazione, naturalmente!

Questo file non sembra davvero un file JSON, ma si può risolvere facilmente passando l'argomento indent=4 a dump():

json_8

Ora il contenuto del file è questo:

{
    "ordinazioni": [
        {
            "taglia": "media",
            "prezzo": 15.67,
            "condimenti": [
                "funghi",
                "salame",
                "basilico"
            ],
            "formaggio_extra": false,
            "consegna": true
        },
        {
            "taglia": "piccola",
            "prezzo": 6.54,
            "condimenti": null,
            "formaggio_extra": true,
            "consegna": false
        }
    ]
}
ordinazioni_nuovo.json

Che differenza! Ecco come ci si aspetta che sia un file JSON.

Ora sai come leggere e scrivere un file JSON usando  load() e dump(). Ora passiamo a esaminare le differenze tra queste funzioni e le funzioni utilizzate per lavorare con le stringhe JSON.

🔹 load() vs loads()

Questa tabella riassume le differenze chiave tra queste due funzioni:

load() loads()
Scopo Crea un oggetto Python da un file JSON Crea un oggetto Python da una stringa
Argomento File JSON Stringa
Valore Restituito Oggetto Python Oggetto Python

💡 Suggerimento: pensa alla "s" in loads() come "load string". Ti aiuterà a ricordare quando usare le due funzioni.

🔸 dump() vs dumps()

Questa tabella riassume le differenze chiave tra queste due funzioni:

dump() dumps()
Scopo Scrive un oggetto nel formato JSON su un file Ottiene una stringa JSON da un oggetto
Argomenti Oggetto + File Oggetto
Valore Restituito None Stringa

💡 Suggerimento: pensa alla "s" in dumps() come "dump string". Ti aiuterà a ricordare quando usare le due funzioni.

🔹 Terminologia Importante  in JSON

Per finire, ci sono due importanti termini che occorre conoscere per lavorare con JSON:

  • Serializzazione: conversione di un oggetto in una stringa JSON.
  • Deserializzazione: conversione di una stringa JSON in un oggetto.

🔸 In Sintesi

  • JSON (JavaScript Object Notation) è un formato usato per rappresentare e memorizzare dati.
  • È comunemente usato per trasferire dati sul web e memorizzare impostazioni di configurazione.
  • I file JSON hanno un'estensione .json.
  • È possibile convertire stringhe JSON in oggetti Python e viceversa.
  • È possibile leggere file JSON e creare oggetti Python dalle coppie chiave-valore.
  • È possibile scrivere file JSON per salvare il contenuto di oggetti Python in formato JSON.

Spero davvero che il mio articolo ti sia piaciuto e che tu lo abbia trovato utile. Ora sai come lavorare con JSON in Python.