Lezioni del modulo (4/4)
Gestione errori: try/except
Quando qualcosa va storto a runtime (una divisione per zero, una chiave
inesistente, un'operazione su tipi incompatibili) Python solleva
un'eccezione. Senza gestione, l'eccezione interrompe il programma. Con
try / except puoi catturarla e decidere cosa fare.
La forma di base
try:
risultato = 10 / 0
except ZeroDivisionError:
risultato = None
risultato # None- il blocco
try:contiene il codice che può fallire; - l'
except <TipoErrore>:viene eseguito solo se quel tipo di errore viene sollevato dentro iltry.
Catturare il messaggio dell'eccezione
Usa as per legare l'oggetto eccezione a un nome:
try:
int("non è un numero")
except ValueError as e:
messaggio = str(e)
messaggio # "invalid literal for int() with base 10: 'non è un numero'"Più tipi insieme
try:
valore = dati[chiave]
except (KeyError, IndexError):
valore = NoneUna tupla di tipi cattura qualunque eccezione di quei tipi (o sottoclassi).
La struttura completa: try / except / else / finally
try:
n = int("42")
except ValueError:
print("non è un numero")
else:
print(f"parsed: {n}") # eseguito solo se NON c'è stata eccezione
finally:
print("eseguito sempre") # eseguito comunque, anche con eccezioneelse— usalo per il codice che dipende dal successo deltry. Tienilo separato per non catturare per sbaglio eccezioni che non c'entrano.finally— pulizia che deve avvenire sempre (chiudere un file, rilasciare una risorsa). Eseguito sia in caso di successo che di errore.
Sollevare un'eccezione: raise
A volte sei tu a voler segnalare che qualcosa è andato storto:
def diviso(a, b):
if b == 0:
raise ValueError("il divisore non può essere zero")
return a / bLe eccezioni "built-in" più comuni che incontrerai e solleverai:
ValueError— il valore ha il tipo giusto ma è inaccettabile (es. parsing).TypeError— il tipo è sbagliato (es.len(42)).KeyError/IndexError— chiave/indice non esistente.ZeroDivisionError— divisione per zero.FileNotFoundError,PermissionError— operazioni su filesystem.
La clausola else e finally nei blocchi try
Un blocco try può definire altre due clausole:
else: eseguita solo se il bloccotrynon solleva alcuna eccezione.finally: eseguita sempre, a prescindere dal fatto che sia avvenuta o meno un'eccezione. È ideale per rilasciare risorse (es. chiudere un file aperto o una connessione a un database).
Prova tu
Scrivi un'espressione che provi a fare int('abc'): se ValueError viene sollevata, assegna a `result` la stringa 'errore'; altrimenti assegna il numero. Valuta `result`.
Mostra suggerimento
int('abc') solleva ValueError.
Soluzione disponibile dopo 3 tentativi
Esercizio di ripasso
Definisci `divide(a, b)` che ritorna a/b ma solleva ValueError con messaggio 'divisore zero' se b è 0. Poi chiama divide(10, 0) dentro un try/except e assegna a `message` la stringa dell'eccezione catturata.
Mostra suggerimento
raise ValueError('...') dentro la funzione; cattura con except ValueError as e.
Soluzione disponibile dopo 3 tentativi
Sfida aggiuntiva
Scrivi un blocco `try-except` per convertire in intero la stringa `text_val = "abc"`. Se la conversione solleva un `ValueError`, assegna a `result` il valore `None`. Altrimenti assegna il numero convertito. Valuta infine `result`.
Mostra suggerimento
Usa try: result = int(text_val) seguita da except ValueError: result = None.
Soluzione disponibile dopo 3 tentativi