Sostieni AppuntiFacili con una piccola donazione su PayPal

Dona con PayPal
AppuntiFacili
Torna Indietro Segnala errore

Gestione Eccezioni

✍️ Dennis Turco 🏷️ Informatica 📘 Python
Ultima modifica:
#python#programmazione#try#except#eccezioni

1. Introduzione

Durante l’esecuzione di un programma Python, possono verificarsi errori. Alcuni di questi sono errori di sintassi, che impediscono l’esecuzione del programma; altri sono eccezioni, cioè errori che si verificano durante l’esecuzione (runtime errors).

Esempi di eccezioni comuni:

  • ValueError: si verifica quando un valore non è del o previsto.
  • ZeroDivisionError: divisione per zero.
  • FileNotFoundError: apertura di un file inesistente.
  • TypeError: operazioni tra i non compatibili (es. sommare stringa e intero).
  • IndexError: accesso a un indice di lista inesistente.

Per gestire in modo controllato le eccezioni, Python mette a disposizione il costrutto:

try → except → else → finally

try-except-finally

Non tutti i blocchi sono obbligatori, ma devono seguire quest’ordine.

2. Blocco Try

Il blocco try contiene il codice che potrebbe generare un’eccezione. Se durante l’esecuzione di quel codice si verifica un’eccezione non gestita, il controllo viene passato ai blocchi except successivi.

Esempio:

try:
    x = int(input("Inserisci un numero: "))
    print("Hai inserito:", x)

Se l’utente inserisce qualcosa che non può essere convertito in intero (es. “abc”), viene sollevata un’eccezione ValueError.

INFO

Il blocco try non serve a prevenire gli errori, ma a gestirli in modo ordinato quando si verificano.

3. Blocco except

except serve per intercettare e gestire le eccezioni. Può essere generico o specifico.

try-except

  1. Esempio base (cattura qualsiasi eccezione)

    try:
        x = int(input("Inserisci un numero: "))
    except:
        print("Si è verificato un errore!")

    WARNING

    Questo approccio è poco raccomandato perché nasconde informazioni utili al debug.

  2. Esempio con o specifico

    try:
        x = int(input("Inserisci un numero: "))
    except ValueError:
        print("Devi inserire un numero valido!")

    Intercetta solo ValueError, lasciando passare eventuali altri errori (es. KeyboardInterrupt).

  3. Più except per i diversi

    try:
        x = int(input("Inserisci un numero: "))
        risultato = 10 / x
    except ValueError:
        print("Non hai inserito un numero!")
    except ZeroDivisionError:
        print("Non puoi dividere per zero!")
  4. Gestire più eccezioni in una sola clausola

    try:
        x = int(input("Inserisci un numero: "))
        risultato = 10 / x
    except (ValueError, ZeroDivisionError):
        print("Errore: input non valido o divisione per zero!")

4. Blocco else

Il blocco else viene eseguito solo se non si è verificata alcuna eccezione nel try. Serve per separare il codice di “successo” da quello di “errore”.

else

Esempio:

try:
    x = int(input("Inserisci un numero: "))
except ValueError:
    print("Errore: non è un numero valido.")
else:
    print("Hai inserito correttamente il numero:", x)

INFO

Usare else migliora la leggibilità e chiarisce l’intento del programmatore: “se tutto è andato bene, esegui questo blocco”.

5. Blocco finally

finally viene sempre eseguito, indipendentemente dal fatto che sia avvenuta o meno un’eccezione. È utile per rilasciare risorse, come file o connessioni a database.

finally

Esempio

try:
    file = open("dati.txt", "r")
    contenuto = file.read()
except FileNotFoundError:
    print("File non trovato!")
else:
    print("File letto con successo.")
finally:
    file.close()
    print("File chiuso.")

INFO

Anche se si verifica un’eccezione, il finally viene eseguito (a meno che il processo non venga terminato forzatamente).

6. Schema Generale

try:
    # codice che potrebbe generare un errore
except oErrore1:
    # gestisce il primo o di errore
except oErrore2:
    # gestisce il secondo o di errore
else:
    # eseguito se non ci sono errori
finally:
    # eseguito sempre

INFO

Note:

  • Possibile avere zero o più blocchi except.
  • else è opzionale e va dopo tutti gli except.
  • finally è opzionale e, se presente, va per ultimo.

7. Rilancio delle Eccezioni (raise)

Possibile rilanciare l’eccezione dopo averla parzialmente gestita, per farla propagare più in alto nello stack:

try:
    x = int(input("Inserisci un numero: "))
except ValueError:
    print("Errore catturato, ma lo rilancio...")
    raise

TIP

raise senza argomenti rilancia l’ultima eccezione catturata. È utile per registrare un errore o effettuare operazioni di pulizia, senza sopprimere l’errore originale.

8. Eccezioni personalizzate

Possibile creare eccezioni custom definendo una classe che eredita da Exception:

class NumeroNegativoError(Exception):
    pass

try:
    n = int(input("Inserisci un numero positivo: "))
    if n < 0:
        raise NumeroNegativoError("Hai inserito un numero negativo!")
except NumeroNegativoError as e:
    print("Errore personalizzato:", e)

Le eccezioni personalizzate migliorano la chiarezza e rendono il codice più robusto.

INFO

Possibile anche aggiungere logica personalizzata alla classe, ad esempio campi aggiuntivi o metodi per formattare il messaggio di errore.

9. Buone pratiche

  1. Evitare except generici, sempre meglio specificare l’eccezione attesa
  2. Loggare le eccezioni importanto con logging
  3. Rilanciare (raise) quando non si è al livello giusto per decidere come gestire l’errore.
  4. Definire eccezioni custom per condizioni di errore logiche dell’applicazione.

10. Quiz a risposta multipla

1) Qual è la differenza principale tra un errore di sintassi e un'eccezione?

2) Cosa accade se si verifica un'eccezione all'interno di un blocco try senza un blocco except corrispondente?

3) Qual è la sintassi corretta per catturare un'eccezione specifica in Python?

4) Qual è lo scopo del blocco else in una struttura try-except?

5) Quale delle seguenti affermazioni sul blocco finally è vera?

6) Come si possono gestire più tipi di eccezioni in un singolo blocco except?

7) Cosa fa l'istruzione 'raise' in Python?

8) Quando si usa 'raise' senza argomenti all'interno di un blocco except?

9) Come si definisce correttamente un'eccezione personalizzata in Python?

10) Qual è una buona pratica nella gestione delle eccezioni?

11. Esercizi

11.1 Esercizio - Conversione Sicura

Scrivere un programma che:

  1. chiede un numero intero all’utente.
  2. stampa il quadrato del numero.
  3. gestisce gli errori in caso di input non valido.

Suggerimento: usare try-except-else.

11.2 Esercizio - Divisione Sicura

Scrivere un programma che:

  1. chiede due numeri (dividendo e divisore).
  2. calcola il risultato della divisione.
  3. gestisce i casi di input non numerico e divisione per zero.
  4. stampa sempre un messaggio finale “Operazione terminata”.

11.3 Esercizio -Eccezione Personalizzata

Crea una classe di eccezione “EtaNonValidaError” e scrivere un programma che:

  1. chiede l’età all’utente.
  2. solleva l’eccezione se l’età è minore di 0 o maggiore di 120.
  3. gestisce l’errore con un messaggio personalizzato.
Prenota una lezione