W3docs

Python JSON

Scopri come usare il modulo json di Python per codificare, decodificare, leggere e scrivere dati JSON, con esempi pratici e gestione degli errori.

Il modulo json integrato in Python ti consente di convertire oggetti Python in testo JSON e viceversa con appena due funzioni nella maggior parte dei casi. Questo capitolo copre tutto il necessario: mappatura dei tipi di dati, dumps/loads per le stringhe, dump/load per i file, stampa formattata, gestione degli errori e serializzazione personalizzata.

Cos'è JSON?

JSON (JavaScript Object Notation) è un formato di scambio dati leggero e testuale. È leggibile dagli esseri umani, indipendente dal linguaggio e il formato predefinito per la maggior parte delle API web.

Un documento JSON è composto da due strutture:

  • Oggetti — raccolte non ordinate di coppie chiave/valore racchiuse in {}. Le chiavi sono sempre stringhe tra virgolette doppie.
  • Array — sequenze ordinate di valori racchiuse in [].

Esempio di documento JSON:

{
  "name": "John Doe",
  "age": 30,
  "city": "New York",
  "hobbies": ["reading", "traveling", "photography"],
  "active": true,
  "score": null
}

Mappatura dei tipi Python–JSON

Quando codifichi o decodifichi JSON, il modulo json di Python converte i tipi in base a questa tabella:

Tipo PythonTipo JSONTipo Python (dopo la decodifica)
dictobject {}dict
list, tuplearray []list
strstring ""str
int, floatnumberint o float
True / Falsetrue / falsebool
NonenullNone

Nota che le tuple diventano array JSON e ritornano come liste Python dopo la decodifica.

Codifica di oggetti Python in stringhe JSON

json.dumps() (dump-string) serializza un oggetto Python in una stringa formattata JSON.

Codifica di base

python— editable, runs on the server

Output:

{"name": "John Doe", "age": 30, "city": "New York", "hobbies": ["reading", "traveling", "photography"]}

Stampa formattata con indent e sort_keys

Per impostazione predefinita json.dumps() produce una stringa compatta su una singola riga. Passa indent per ottenere output leggibile dagli esseri umani, e sort_keys=True per ordinare le chiavi del dizionario in ordine alfabetico:

import json

person = {
    "name": "John Doe",
    "age": 30,
    "city": "New York",
    "hobbies": ["reading", "traveling", "photography"]
}

print(json.dumps(person, indent=2, sort_keys=True))

Output:

{
  "age": 30,
  "city": "New York",
  "hobbies": [
    "reading",
    "traveling",
    "photography"
  ],
  "name": "John Doe"
}

Usa indent=2 o indent=4 quando scrivi file di configurazione o fai debug delle risposte API — rende le strutture annidate facili da leggere.

Decodifica di stringhe JSON in oggetti Python

json.loads() (load-string) analizza una stringa JSON e restituisce l'equivalente oggetto Python.

Decodifica di base

python— editable, runs on the server

Output:

{'name': 'John Doe', 'age': 30, 'city': 'New York', 'hobbies': ['reading', 'traveling', 'photography']}
<class 'dict'>
John Doe

Il valore decodificato è un normale dizionario Python, quindi puoi accedere alle sue chiavi con [] o .get(), iterarlo con for e così via.

Gestione di JSON non valido

Se l'input non è JSON valido, json.loads() solleva json.JSONDecodeError. Cattura sempre questo errore quando lavori con dati provenienti da fonti esterne:

import json

raw = '{"name": "Alice", "age":}'   # invalid — missing value

try:
    data = json.loads(raw)
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e}")

Output:

Invalid JSON: Expecting value: line 1 column 24 (char 23)

Consulta il capitolo Python try/except per una guida completa alla gestione delle eccezioni.

Lavorare con JSON annidato

Gli oggetti JSON possono contenere altri oggetti e array a qualsiasi profondità. Accedi ai valori annidati usando la notazione [] concatenata:

python— editable, runs on the server

Output:

John
traveling

Per strutture profondamente annidate, considera l'uso di .get() con un valore predefinito per evitare KeyError su chiavi mancanti:

city = person.get("address", {}).get("city", "unknown")

Il capitolo sui dizionari annidati illustra i pattern per lavorare con dizionari Python profondamente annidati.

Lettura e scrittura di file JSON

json.dump() scrive su un oggetto file, e json.load() legge da uno. Questi sono i corrispondenti per file di dumps/loads.

Scrittura di JSON su un file

import json

data = {"name": "Alice", "scores": [95, 87, 92]}

with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

Questo crea data.json con contenuto formattato. L'uso di with open(...) garantisce che il file venga chiuso automaticamente — consulta la gestione dei file Python per i dettagli.

Lettura di JSON da un file

import json

with open("data.json") as f:
    data = json.load(f)

print(data)
print(data["scores"])

Output (assumendo il file scritto sopra):

{'name': 'Alice', 'scores': [95, 87, 92]}
[95, 87, 92]

Esempio di ciclo completo

import json

# Write
config = {"host": "localhost", "port": 5432, "debug": False}
with open("config.json", "w") as f:
    json.dump(config, f, indent=2)

# Read back
with open("config.json") as f:
    loaded = json.load(f)

print(loaded["port"])   # 5432
print(type(loaded["port"]))   # <class 'int'>

Recupero di JSON da un'API web

Nella maggior parte dei progetti decodificherai JSON proveniente da una risposta HTTP. La popolare libreria requests rende questo semplice:

import requests

response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
response.raise_for_status()   # raises an error for 4xx/5xx responses
data = response.json()        # equivalent to json.loads(response.text)

print(data["title"])
print(data["completed"])

response.json() chiama json.loads() internamente. Chiama sempre raise_for_status() prima di analizzare la risposta, così una richiesta fallita non restituisce silenziosamente un corpo di errore.

Serializzazione personalizzata con default

Il modulo json non è in grado di codificare oggetti Python arbitrari (come datetime.date) per impostazione predefinita. Passa un callable default o una sottoclasse JSONEncoder personalizzata per gestirli:

import json
import datetime

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.date):
            return obj.isoformat()
        return super().default(obj)

event = {"name": "Conference", "date": datetime.date(2024, 1, 15)}
print(json.dumps(event, cls=DateEncoder))

Output:

{"name": "Conference", "date": "2024-01-15"}

L'oggetto date viene convertito nella sua stringa ISO 8601 prima della serializzazione.

Deserializzazione personalizzata con object_hook

object_hook viene chiamato per ogni oggetto JSON (dict) durante la decodifica. Puoi usarlo per trasformare i dati al volo — per esempio, convertendo valori stringa nei tipi Python corretti:

import json

def as_record(d):
    """Convert age field from string to int if present."""
    if "age" in d:
        d["age"] = int(d["age"])
    return d

raw = '{"name": "Bob", "age": "25"}'
person = json.loads(raw, object_hook=as_record)
print(person)
print(type(person["age"]))   # <class 'int'>

Output:

{'name': 'Bob', 'age': 25}
<class 'int'>

Riferimento rapido

FunzioneDirezioneSorgente/destinazione
json.dumps(obj)Python → JSONrestituisce una str
json.loads(s)JSON → Pythonlegge da una str
json.dump(obj, f)Python → JSONscrive su un file
json.load(f)JSON → Pythonlegge da un file

Parametri opzionali principali:

  • indent=2 — stampa formattata con rientro di 2 spazi
  • sort_keys=True — ordina le chiavi del dizionario in ordine alfabetico
  • cls=MyEncoder — usa una sottoclasse JSONEncoder personalizzata
  • object_hook=fn — trasforma ogni object dict decodificato

Pratica

Pratica
Quale funzione Python converte un dizionario Python in una stringa formattata JSON?
Quale funzione Python converte un dizionario Python in una stringa formattata JSON?
Was this page helpful?