Errori ed eccezioni possono portare al fallimento del programma o a comportamenti imprevisti, e Python include un set solido di strumenti per migliorarne la stabilità.
Errori ed eccezioni possono portare a comportamenti imprevisti o persino interrompere l’esecuzione di un programma. Python fornisce diverse funzioni e meccanismi per gestire questi problemi e migliorare la robustezza del codice. In questo tutorial, impareremo i vari tipi di errori e le funzioni integrate con esempi.
Un errore è un problema critico nel codice da cui in genere non si può recuperare a runtime, come una sintassi malformata o un’indentazione errata.
Un’eccezione è un evento a runtime che interrompe il normale flusso del programma ma può essere intercettato e gestito, permettendo al programma di continuare.
Sebbene le eccezioni si verifichino a runtime, alcuni errori come SyntaxError e IndentationError vengono intercettati dal parser prima ancora che il programma venga eseguito.
In parole semplici, l’errore è un problema critico che una normale applicazione non dovrebbe intercettare, mentre un’eccezione è una condizione che un programma dovrebbe intercettare.
Approfondiamo errori ed eccezioni osservando vari esempi. Per eseguirli facilmente, puoi creare gratuitamente un workbook DataLab con Python preinstallato e tutti gli esempi di codice.
Errori in Python
Ecco un esempio di errore di sintassi in cui un return al di fuori della funzione non ha senso. Non dovremmo gestire gli errori in un programma. Invece, dobbiamo creare una funzione che restituisca la stringa.
Input In [1]return"DataCamp"^
SyntaxError:'return' outside function
Offerto da
Abbiamo creato la funzione ma con l’indentazione sbagliata. Non dovremmo gestire gli errori di indentazione a runtime. Possiamo correggerli manualmente o usare strumenti di formattazione del codice.
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Input In [4],in<cell line:1>()---->1 test =1/0
ZeroDivisionError: division by zeroOfferto da
Le eccezioni NameError sono piuttosto comuni quando una variabile non viene trovata. Possiamo gestire anche questa eccezione sostituendo la variabile o stampando un avviso.
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [5],in<cell line:1>()---->1 y = test
NameError
Offerto da
Eccezioni integrate in Python
Ecco l’elenco delle eccezioni predefinite di Python con descrizioni:
AssertionError: sollevata quando l’istruzione assert fallisce.
EOFError: sollevata quando la funzione input() incontra la condizione di fine file.
AttributeError: sollevata quando l’assegnazione o il riferimento a un attributo fallisce.
TabError: sollevata quando le indentazioni contengono tabulazioni o spazi incoerenti.
ImportError: sollevata quando l’import del modulo fallisce.
IndexError: si verifica quando l’indice di una sequenza è fuori intervallo
KeyboardInterrupt: sollevata quando l’utente inserisce i tasti di interruzione (Ctrl + C o Canc).
RuntimeError: si verifica quando un errore non rientra in alcuna categoria.
NameError: sollevata quando una variabile non viene trovata nello scope locale o globale.
MemoryError: sollevata quando i programmi esauriscono la memoria.
ValueError: si verifica quando un’operazione o funzione riceve un argomento del tipo corretto ma con un valore sbagliato.
ZeroDivisionError: sollevata quando dividi un valore o una variabile per zero.
SyntaxError: sollevata dal parser quando la sintassi Python è errata.
IndentationError: si verifica quando c’è un’indentazione sbagliata.
SystemError: sollevata quando l’interprete rileva un errore interno.
Puoi trovare l’elenco completo di errori ed eccezioni in Python consultando la documentazione.
Approfondisci le eccezioni in Python seguendo il nostro corso Programmazione orientata agli oggetti in Python. Imparerai a creare classi e sfruttare ereditarietà e polimorfismo per riutilizzare e ottimizzare il codice.
Gestione delle eccezioni con try, except, else e finally
Dopo aver visto errori ed eccezioni, impareremo a gestirli usando i blocchi try, except, else e finally.
Che cosa intendiamo per gestirli? In circostanze normali, questi errori interrompono l’esecuzione del codice e mostrano il messaggio di errore. Per creare sistemi stabili, dobbiamo prevedere questi errori e proporre soluzioni alternative o messaggi di avviso.
In questa sezione, vedremo cosa fa ciascun blocco e come usarli per scrivere codice robusto.
L’istruzione try ed except
Il modo più semplice per gestire le eccezioni in Python è usare il blocco try e except.
Esegui il codice all’interno dell’istruzione try.
Quando viene sollevata un’eccezione, esegui il codice sotto l’istruzione except.
Invece di fermarsi all’errore o all’eccezione, il nostro codice passerà a soluzioni alternative.
Esempio semplice
Nel primo esempio, proveremo a stampare la variabile x non definita. In condizioni normali, dovrebbe generare l’errore e interrompere l’esecuzione, ma con il blocco try e except possiamo modificare il comportamento del flusso.
Il programma eseguirà il codice sotto l’istruzione try.
Dato che x non è definita, verrà eseguito l’except e verrà stampato l’avviso.
try:print(x)except:print("An exception has occurred!")Offerto da
Nel secondo esempio, useremo più istruzioni except per gestire più tipi di eccezioni.
Se viene sollevata un’eccezione ZeroDivisionError, il programma stamperà "You cannot divide a value with zero."
Le restanti eccezioni stamperanno “Something else went wrong.”
Questo ci permette di scrivere codice flessibile in grado di gestire più eccezioni contemporaneamente senza bloccarsi.
Nota: evita di usare un except: “nudo” senza specificare il tipo di eccezione — intercetta tutto, compresi KeyboardInterrupt e SystemExit, il che può rendere impossibile chiudere il programma e nascondere bug non correlati. Intercetta sempre l’eccezione specifica che ti aspetti, ad esempio except ZeroDivisionError:.
try:print(1/0)except ZeroDivisionError:print("You cannot divide a value with zero")except:print("Something else went wrong")Offerto da
Nel codice seguente, leggiamo un file CSV e, quando viene sollevata l’eccezione FileNotFoundError, il codice stamperà l’errore e un messaggio aggiuntivo sul file data.csv.
Sì, possiamo stampare i messaggi di errore predefiniti senza interrompere l’esecuzione.
try:withopen('data.csv')asfile:
read_data =file.read()except FileNotFoundError as fnf_error:print(fnf_error)print("Explanation: We cannot load the 'data.csv' file")Offerto da
[Errno 2] No such fileor directory:'data.csv'
Explanation: We cannot load the 'data.csv'fileOfferto da
try con la clausola else
Abbiamo visto try e except, e ora vedremo l’istruzione else.
Quando l’istruzione try non solleva alcuna eccezione, il codice entra nel blocco else. È il rimedio o un’opzione di fallback quando ti aspetti che una parte dello script possa generare un’eccezione. In genere si usa in una breve sezione di setup o verifica in cui non vuoi che certi errori vengano nascosti.
Nota: nel blocco try-except, puoi usare else dopo tutte le istruzioni except.
Esempio semplice
Aggiungiamo l’istruzione else all’esempio con ZeroDivisionError. Come si vede, quando non ci sono eccezioni, viene eseguita la print sotto l’istruzione else, mostrando il risultato.
try:
result =1/3except ZeroDivisionError as err:print(err)else:print(f"Your answer is {result}")Offerto da
Impariamo di più creando una semplice funzione e testandola in vari scenari.
La funzione find_nth_value() ha x (lista) e n (numero di indice) come argomenti. Abbiamo creato un blocco try, except e else per gestire l’eccezione IndexError.
x =[5,8,9,13]deffind_nth_value(x,n):try:
result = x[n]except IndexError as err:print(err)else:print("Your answer is ", result)Offerto da
La lista x ha quattro valori e la testeremo per gli indici 6 e 2.
# Testing
find_nth_value(x,6)
find_nth_value(x,2)Offerto da
Con n=6, è stata sollevata l’eccezione IndexError e abbiamo visto il messaggio predefinito “list index out of range”.
Con n=2, non è stata sollevata alcuna eccezione e la funzione ha stampato il risultato che si trova sotto l’istruzione else.
La parola chiave finally in un blocco try-except viene sempre eseguita, indipendentemente dal fatto che ci sia un’eccezione o meno. Il blocco finally viene sempre eseguito dopo try, except ed else, a prescindere dal fatto che un’eccezione sia stata sollevata o gestita. È molto utile per ripulire risorse e chiudere oggetti, in particolare i file.
La funzione divide è stata creata per gestire le eccezioni ZeroDivisionError e mostrare il risultato quando non ci sono eccezioni. Indipendentemente dall’esito, eseguirà sempre finally per stampare “Code by DataCamp” in verde.
defdivide(x,y):try:
result = x/y
except ZeroDivisionError:print("Please change 'y' argument to non-zero value")except:print("Something went wrong")else:print(f"Your answer is {result}")finally:print("\033[92m Code by DataCamp\033[00m")Offerto da
Nel primo test, dividiamo 1 per 0, il che dovrebbe sollevare l’eccezione ZeroDivisionError e stampare il messaggio. Come si vede, abbiamo una riga aggiuntiva dopo il messaggio di errore.
Invece di un intero, abbiamo aggiunto una stringa come secondo argomento, che ha sollevato un’eccezione diversa da ZeroDivisionError con un messaggio diverso.
In tutti e tre gli scenari c’è una cosa in comune. Il codice esegue sempre la funzione print sotto l’istruzione finally.
Se sei alle prime armi con Python e vuoi programmare come un vero developer, prova il nostro percorso di competenze Python Programming. Imparerai a scrivere codice efficiente, funzioni Python, ingegneria del software, unit test e programmazione orientata agli oggetti.
Gestione annidata delle eccezioni in Python
Abbiamo bisogno della gestione annidata delle eccezioni quando prepariamo il programma a gestire più eccezioni in sequenza. Per esempio, possiamo aggiungere un altro blocco try-except sotto l’istruzione else. Quindi, se la prima istruzione non solleva un’eccezione, controlla la seconda istruzione con l’altra parte del codice.
Modifica della funzione divide
Abbiamo modificato la funzione divide dell’esempio precedente e aggiunto un blocco try-except annidato sotto l’istruzione else. Quindi, se non c’è AttributeError, eseguirà l’else e controllerà il nuovo codice per l’eccezione ZeroDivisionError.
defdivide(x,y):try:
value =50
x.append(value)except AttributeError as atr_err:print(atr_err)else:try:
result =[i / y for i in x]print( result )except ZeroDivisionError:print("Please change 'y' argument to non-zero value")finally:print("\033[92m Code by DataCamp\033[00m")Offerto da
Nel primo scenario, forniamo la lista di quattro valori x e il denominatore 3. Lo script aggiungerà 50 alla lista, dividerà ciascun valore della lista per 3 e mostrerà il risultato.
Please change 'y' argument to non-zero value
Code by DataCampOfferto da
Esempio di modifica file
Vediamo esempi più pratici di caricamento del file, scrittura di un testo e chiusura del file.
La funzione file_editor() farà quanto segue:
Controlla l’eccezione FileNotFoundError per la funzione open().
Se l’eccezione esterna non viene sollevata, controllerà l’eccezione per la funzione write().
In ogni caso, dopo aver aperto il file, lo chiuderà eseguendo l’istruzione finally.
Se l’istruzione try esterna solleva l’eccezione, restituirà il messaggio di errore con un percorso file non valido.
deffile_editor(path,text):try:
data =open(path)try:
data.write(text)except:print("Unable to write the data. Please add an append: 'a' or write: 'w' parameter to the open() function.")finally:
data.close()except:print(f"{path} file is not found!!")Offerto da
Nel primo scenario, forniamo il percorso del file e il testo.
path ="data.txt"
text ="DataLab: Share your data analysis in a cloud-based environment--no installation required."
file_editor(path,text)Offerto da
Viene sollevata l’eccezione interna, poiché la funzione write() non riesce ad aggiungere il testo.
Unable to write the data. Please add an append:'a'or write:'w' parameter to the open() function.Offerto da
Per risolvere questo problema, dobbiamo cambiare la terza riga da data = open(path) a data = open(path, 'a'). Ci permetterà di aggiungere nuovo testo al file.
Dopo aver rieseguito la funzione, abbiamo aggiunto correttamente il testo al file.
La gestione annidata delle eccezioni non è consigliata perché rende la gestione più complessa; gli sviluppatori usano più blocchi try-except per creare una gestione sequenziale semplice.
Nota: puoi anche aggiungere un blocco try-except annidato sotto l’istruzione try o except. Dipende semplicemente dalle tue esigenze.
Sollevare eccezioni in Python
Oltre a intercettare le eccezioni, puoi sollevarle deliberatamente usando la parola chiave raise. È utile per far rispettare regole di business o la validazione degli input. Fornisce un segnale che qualcosa non va prima che causi un errore più difficile da debuggare più avanti nella catena.
Per generare un’eccezione, dobbiamo usare la parola chiave raise seguita dal nome dell’eccezione.
Esempio di ValueError sollevato
Possiamo sollevare eccezioni semplicemente aggiungendo la parola chiave raise nell’istruzione if/else.
Nell’esempio, solleviamo ValueError se il valore supera 1.000. Abbiamo impostato il valore a 2.000, rendendo l’istruzione ifTRUE e sollevando ValueError con un messaggio personalizzato. Il messaggio di errore personalizzato ti aiuta a individuare velocemente il problema.
value =2_000if value >1_000:# raise the ValueErrorraise ValueError("Please add a value lower than 1,000")else:print("Congratulations! You are the winner!!")Offerto da
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)---->4raise ValueError("Please add a value lower than 1,000")5else:6print("Congratulations! You are the winner!!")
ValueError: Please add a value lower than 1,000Offerto da
Esempio di eccezione sollevata
Possiamo anche sollevare una qualunque eccezione integrata di Python se la condizione è soddisfatta. Nel nostro caso, abbiamo sollevato un’eccezione generica con il messaggio di errore.
if value >1_000:# raise the Exceptionraise Exception("Please add a value lower than 1,000")else:print("Congratulations! You are the winner!!")Offerto da
---------------------------------------------------------------------------
Exception Traceback (most recent call last)---->3raise Exception("Please add a value lower than 1,000")4else:5print("Congratulations! You are the winner!!")
Exception: Please add a value lower than 1,000Offerto da
Esempio di gestione di un’eccezione sollevata
Possiamo anche creare un’eccezione personalizzata e gestirla usando il blocco try-except.
Nell’esempio, abbiamo aggiunto un caso di value error sotto l’istruzione try.
Quindi, come funzionerà? Invece di sollevare l’eccezione e terminare il programma, mostrerà il messaggio di errore che abbiamo fornito.
value =2_000try:if value >1_000:# raise the ValueErrorraise ValueError("Please add a value lower than 1,000")else:print("Congratulations! You are the winner!!")# if false then raise the value errorexcept ValueError as e:print(e)Offerto da
Questo tipo di gestione delle eccezioni ci aiuta a prepararci per errori non coperti da Python e specifici dei requisiti della tua applicazione.
Oltre a sollevare eccezioni singole, puoi concatenare eccezioni usando raise ... from. Questo preserva l’eccezione originale come contesto, rendendo i traceback molto più chiari quando un errore ne causa un altro.
try:open("config.json")except FileNotFoundError as e:raise RuntimeError("App failed to start: config file missing")from eOfferto da
FileNotFoundError:[Errno 2] No such fileor directory:'config.json'
The above exception was the direct cause of the following exception:
RuntimeError: App failed to start: config file missingOfferto da
La parte from e imposta l’attributo __cause__ sulla nuova eccezione, così chiunque legga il traceback può vedere esattamente cosa l’ha scatenata. È particolarmente utile nelle applicazioni più grandi in cui le eccezioni attraversano più livelli di codice.
Novità in Python 3.10 - 3.13 per la gestione delle eccezioni?
Alcuni sviluppi importanti sono stati aggiunti nelle versioni più recenti di Python, come la 3.10 e la 3.11, da quando questo post è stato originariamente scritto:
1. Pattern matching strutturale in Python 3.10
Python 3.10 ha introdotto il pattern matching strutturale, che può essere usato per gestire le eccezioni in modo più elegante abbinando i tipi di errore in un’istruzione match. È particolarmente utile quando si gestiscono più tipi di eccezioni in modo più leggibile. Esempio:
try:
result =1/0except Exception as e:match e:case ZeroDivisionError():print("You cannot divide by zero.")case NameError():print("Variable not defined.")case_:print("An unexpected error occurred.")Offerto da
2. Localizzazione fine degli errori nei traceback (Python 3.11)
I traceback in Python 3.11 ora mostrano posizioni di errore precise, rendendo più semplice il debug delle eccezioni.
Con Python 3.11, i traceback evidenziano l’esatta sottoespressione che causa l’eccezione:
ZeroDivisionError: division by zero
(1+2)*(3/0)^Offerto da
3. Gruppi di eccezioni ed except* (Python 3.11)
Python 3.11 ha introdotto i gruppi di eccezioni per gestire più eccezioni in un singolo blocco usando except*. È utile per gestire codice asincrono o scenari in cui potrebbero essere sollevate più eccezioni. Esempio:
try:raise ExceptionGroup("Multiple errors",[ValueError("Bad value"), TypeError("Bad type")])except* ValueError as ve:print(f"Handling ValueError: {ve}")except* TypeError as te:print(f"Handling TypeError: {te}")Offerto da
4. Metodo add_note per le eccezioni (Python 3.11)
Le eccezioni ora hanno un metodo add_note(), che consente agli sviluppatori di aggiungere note personalizzate alle eccezioni per un debug migliore. Esempio:
try:raise ValueError("Invalid input")except ValueError as e:
e.add_note("This happened while processing user input.")
e.add_note("Consider validating input before processing.")raiseOfferto da
ValueError: Invalid input
Notes:- This happened while processing user input.- Consider validating input before processing.Offerto da
5. PEP 654: Gestione migliore delle eccezioni annidate
Con i gruppi di eccezioni, le eccezioni annidate sono ora più facili da eseguire il debug e da gestire, specialmente in flussi di lavoro complessi come multiprocessing o attività asincrone.
6. Messaggi di errore migliorati (Python 3.12)
Python 3.12 ha proseguito uno sforzo di lunga data per rendere i messaggi di errore più specifici e utili. Ad esempio, i messaggi di NameError ora suggeriscono variabili con nomi simili presenti nello scope, e gli errori di attributo su tipi comuni forniscono suggerimenti più mirati:
# Python 3.12+
my_list =[1,2,3]
my_list.appendd(4)Offerto da
AttributeError:'list'object has no attribute 'appendd'. Did you mean:'append'?Offerto da
7. Traceback colorati (Python 3.13)
Python 3.13 ha introdotto per impostazione predefinita traceback colorati nell’interprete interattivo. Tipi di errore, numeri di riga e messaggi sono ora evidenziati con colori diversi, rendendo molto più veloce individuare e capire cosa è andato storto — soprattutto in traceback lunghi con più eccezioni concatenate.
Conclusione
Sia i test unitari sia la gestione delle eccezioni sono parti fondamentali della programmazione in Python che rendono il tuo codice pronto per la produzione e resistente agli errori. In questo tutorial, abbiamo visto eccezioni ed errori in Python e come gestirli. Inoltre, abbiamo visto blocchi try-except annidati più complessi e creato blocchi di eccezioni personalizzati in base alle esigenze.
Questi strumenti e meccanismi sono essenziali, ma gran parte del lavoro si svolge tramite semplici blocchi try e except. Dove try cerca le eccezioni sollevate dal codice ed except gestisce tali eccezioni.
Se ti sembra tutto confuso e non sai da dove iniziare, completa il nostro corso Introduction to Functions in Python per capire scope, funzioni lambda e gestione degli errori. Puoi anche iscriverti al career track Python Programmer per acquisire competenze spendibili e diventare uno sviluppatore Python professionista.
In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.
FAQ
Qual è la differenza tra un errore e un’eccezione in Python?⌄
Un errore in Python è in genere un problema più grave che impedisce al programma di proseguire, come un errore di sintassi, che indica che la struttura del codice è errata. Un’eccezione, invece, è una condizione che interrompe il normale flusso del programma ma può essere gestita all’interno del programma usando i blocchi try-except, permettendo al programma di continuare l’esecuzione.
Puoi intercettare più eccezioni in un singolo blocco try-except?⌄
Sì, Python ti permette di intercettare più eccezioni in un singolo blocco try-except usando una tupla di tipi di eccezioni. Per esempio: except (TypeError, ValueError):. Questo gestirà sia un TypeError che un ValueError nello stesso blocco.
Come puoi creare un’eccezione personalizzata in Python?⌄
Puoi creare un’eccezione personalizzata definendo una nuova classe che eredita dalla classe integrata Exception. Per esempio:
Qual è lo scopo del blocco else in una struttura try-except?⌄
Il blocco else viene eseguito se il blocco try non solleva un’eccezione. È utile per il codice che dovrebbe essere eseguito solo se il blocco try ha successo, mantenendo il codice pulito e separando la gestione degli errori dal normale percorso di esecuzione.
Perché il blocco finally è importante nella gestione delle eccezioni?⌄
Il blocco finally viene sempre eseguito, indipendentemente dal fatto che un’eccezione sia sollevata o meno. Viene tipicamente usato per operazioni di pulizia, come chiudere file o rilasciare risorse, per garantire che tali azioni vengano eseguite in ogni circostanza.
Come puoi sopprimere le eccezioni in Python?⌄
Puoi sopprimere le eccezioni usando il context manager contextlib.suppress. Ti consente di specificare i tipi di eccezioni da ignorare. Per esempio:
from contextlib import suppress
with suppress(FileNotFoundError):open('non_existent_file.txt')Offerto da
Cosa succede se un’eccezione non viene intercettata in un programma Python?⌄
Se un’eccezione non viene intercettata, si propaga lungo lo stack delle chiamate e, se resta non gestita, termina il programma, stampando a console un traceback che mostra dove si è verificata.
Puoi rilanciare un’eccezione dopo averla intercettata?⌄
Sì, puoi rilanciare un’eccezione usando l’istruzione raise senza argomenti in un blocco except. È utile quando vuoi registrare un errore o eseguire altre azioni prima di consentire all’eccezione di propagarsi ulteriormente.
Esiste un modo per gestire tutte le eccezioni in Python?⌄
Anche se è possibile intercettare tutte le eccezioni usando un except: nudo, in genere non è consigliato perché può intercettare eccezioni inattese e rendere difficile il debug. È meglio intercettare eccezioni specifiche o usare except Exception: per evitare di intercettare eccezioni che terminano il sistema, come SystemExit e KeyboardInterrupt.
Come distingui tra un errore di sintassi e un’eccezione a runtime in termini di momento in cui si verificano?⌄
Gli errori di sintassi vengono rilevati in fase di compilazione, cioè l’interprete Python li intercetta prima che il programma inizi l’esecuzione. Le eccezioni a runtime si verificano durante l’esecuzione quando l’interprete incontra un’operazione che non può eseguire, come dividere per zero o accedere a una variabile inesistente.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Errori ed eccezioni possono portare a comportamenti imprevisti o persino interrompere l’esecuzione di un programma. Python fornisce diverse funzioni e meccanismi per gestire questi problemi e migliorare la robustezza del codice. In questo tutorial, impareremo i vari tipi di errori e le funzioni integrate con esempi.
Sebbene le eccezioni si verifichino a runtime, alcuni errori come
SyntaxErroreIndentationErrorvengono intercettati dal parser prima ancora che il programma venga eseguito.In parole semplici, l’errore è un problema critico che una normale applicazione non dovrebbe intercettare, mentre un’eccezione è una condizione che un programma dovrebbe intercettare.
Approfondiamo errori ed eccezioni osservando vari esempi. Per eseguirli facilmente, puoi creare gratuitamente un workbook DataLab con Python preinstallato e tutti gli esempi di codice.
Errori in Python
Ecco un esempio di errore di sintassi in cui un return al di fuori della funzione non ha senso. Non dovremmo gestire gli errori in un programma. Invece, dobbiamo creare una funzione che restituisca la stringa.
Abbiamo creato la funzione ma con l’indentazione sbagliata. Non dovremmo gestire gli errori di indentazione a runtime. Possiamo correggerli manualmente o usare strumenti di formattazione del codice.
Eccezioni in Python
Abbiamo incontrato un’eccezione
ZeroDivisionError. Possiamo gestirla a runtime usando i blocchitryeexcept.Le eccezioni
NameErrorsono piuttosto comuni quando una variabile non viene trovata. Possiamo gestire anche questa eccezione sostituendo la variabile o stampando un avviso.Eccezioni integrate in Python
Ecco l’elenco delle eccezioni predefinite di Python con descrizioni:
AssertionError: sollevata quando l’istruzione assert fallisce.EOFError: sollevata quando la funzioneinput()incontra la condizione di fine file.AttributeError: sollevata quando l’assegnazione o il riferimento a un attributo fallisce.TabError: sollevata quando le indentazioni contengono tabulazioni o spazi incoerenti.ImportError: sollevata quando l’import del modulo fallisce.IndexError: si verifica quando l’indice di una sequenza è fuori intervalloKeyboardInterrupt: sollevata quando l’utente inserisce i tasti di interruzione (Ctrl + C o Canc).RuntimeError: si verifica quando un errore non rientra in alcuna categoria.NameError: sollevata quando una variabile non viene trovata nello scope locale o globale.MemoryError: sollevata quando i programmi esauriscono la memoria.ValueError: si verifica quando un’operazione o funzione riceve un argomento del tipo corretto ma con un valore sbagliato.ZeroDivisionError: sollevata quando dividi un valore o una variabile per zero.SyntaxError: sollevata dal parser quando la sintassi Python è errata.IndentationError: si verifica quando c’è un’indentazione sbagliata.SystemError: sollevata quando l’interprete rileva un errore interno.Puoi trovare l’elenco completo di errori ed eccezioni in Python consultando la documentazione.
Approfondisci le eccezioni in Python seguendo il nostro corso Programmazione orientata agli oggetti in Python. Imparerai a creare classi e sfruttare ereditarietà e polimorfismo per riutilizzare e ottimizzare il codice.
Gestione delle eccezioni con try, except, else e finally
Dopo aver visto errori ed eccezioni, impareremo a gestirli usando i blocchi
try,except,elseefinally.Che cosa intendiamo per gestirli? In circostanze normali, questi errori interrompono l’esecuzione del codice e mostrano il messaggio di errore. Per creare sistemi stabili, dobbiamo prevedere questi errori e proporre soluzioni alternative o messaggi di avviso.
In questa sezione, vedremo cosa fa ciascun blocco e come usarli per scrivere codice robusto.
L’istruzione try ed except
Il modo più semplice per gestire le eccezioni in Python è usare il blocco
tryeexcept.Esegui il codice all’interno dell’istruzione
try.Quando viene sollevata un’eccezione, esegui il codice sotto l’istruzione
except.Invece di fermarsi all’errore o all’eccezione, il nostro codice passerà a soluzioni alternative.
Esempio semplice
Nel primo esempio, proveremo a stampare la variabile
xnon definita. In condizioni normali, dovrebbe generare l’errore e interrompere l’esecuzione, ma con il bloccotryeexceptpossiamo modificare il comportamento del flusso.try.xnon è definita, verrà eseguito l’except e verrà stampato l’avviso.Esempio con più except
Nel secondo esempio, useremo più istruzioni
exceptper gestire più tipi di eccezioni.ZeroDivisionError, il programma stamperà "You cannot divide a value with zero."Questo ci permette di scrivere codice flessibile in grado di gestire più eccezioni contemporaneamente senza bloccarsi.
Nota: evita di usare un
except:“nudo” senza specificare il tipo di eccezione — intercetta tutto, compresiKeyboardInterrupteSystemExit, il che può rendere impossibile chiudere il programma e nascondere bug non correlati. Intercetta sempre l’eccezione specifica che ti aspetti, ad esempioexcept ZeroDivisionError:.Esempio di caricamento file
Ora, vediamo un esempio più pratico.
Nel codice seguente, leggiamo un file CSV e, quando viene sollevata l’eccezione
FileNotFoundError, il codice stamperà l’errore e un messaggio aggiuntivo sul filedata.csv.Sì, possiamo stampare i messaggi di errore predefiniti senza interrompere l’esecuzione.
try con la clausola else
Abbiamo visto
tryeexcept, e ora vedremo l’istruzioneelse.Quando l’istruzione
trynon solleva alcuna eccezione, il codice entra nel bloccoelse. È il rimedio o un’opzione di fallback quando ti aspetti che una parte dello script possa generare un’eccezione. In genere si usa in una breve sezione di setup o verifica in cui non vuoi che certi errori vengano nascosti.Nota: nel blocco try-except, puoi usare
elsedopo tutte le istruzioniexcept.Esempio semplice
Aggiungiamo l’istruzione
elseall’esempio conZeroDivisionError. Come si vede, quando non ci sono eccezioni, viene eseguita la print sotto l’istruzioneelse, mostrando il risultato.Esempio con IndexError ed else
Impariamo di più creando una semplice funzione e testandola in vari scenari.
La funzione
find_nth_value()hax(lista) en(numero di indice) come argomenti. Abbiamo creato un bloccotry,excepteelseper gestire l’eccezioneIndexError.La lista
xha quattro valori e la testeremo per gli indici 6 e 2.IndexErrore abbiamo visto il messaggio predefinito “list index out of range”.else.La parola chiave finally in Python
La parola chiave
finallyin un bloccotry-exceptviene sempre eseguita, indipendentemente dal fatto che ci sia un’eccezione o meno. Il bloccofinallyviene sempre eseguito dopotry,exceptedelse, a prescindere dal fatto che un’eccezione sia stata sollevata o gestita. È molto utile per ripulire risorse e chiudere oggetti, in particolare i file.La funzione
divideè stata creata per gestire le eccezioniZeroDivisionErrore mostrare il risultato quando non ci sono eccezioni. Indipendentemente dall’esito, eseguirà semprefinallyper stampare “Code by DataCamp” in verde.Nel primo test, dividiamo 1 per 0, il che dovrebbe sollevare l’eccezione
ZeroDivisionErrore stampare il messaggio. Come si vede, abbiamo una riga aggiuntiva dopo il messaggio di errore.Quando forniamo un input valido, mostra il risultato eseguendo i blocchi
elseefinally.Invece di un intero, abbiamo aggiunto una stringa come secondo argomento, che ha sollevato un’eccezione diversa da
ZeroDivisionErrorcon un messaggio diverso.In tutti e tre gli scenari c’è una cosa in comune. Il codice esegue sempre la funzione print sotto l’istruzione
finally.Se sei alle prime armi con Python e vuoi programmare come un vero developer, prova il nostro percorso di competenze Python Programming. Imparerai a scrivere codice efficiente, funzioni Python, ingegneria del software, unit test e programmazione orientata agli oggetti.
Gestione annidata delle eccezioni in Python
Abbiamo bisogno della gestione annidata delle eccezioni quando prepariamo il programma a gestire più eccezioni in sequenza. Per esempio, possiamo aggiungere un altro blocco try-except sotto l’istruzione
else. Quindi, se la prima istruzione non solleva un’eccezione, controlla la seconda istruzione con l’altra parte del codice.Modifica della funzione divide
Abbiamo modificato la funzione
dividedell’esempio precedente e aggiunto un blocco try-except annidato sotto l’istruzioneelse. Quindi, se non c’èAttributeError, eseguirà l’elsee controllerà il nuovo codice per l’eccezioneZeroDivisionError.Nel primo scenario, forniamo la lista di quattro valori
xe il denominatore 3. Lo script aggiungerà 50 alla lista, dividerà ciascun valore della lista per 3 e mostrerà il risultato.La funzione è stata eseguita correttamente senza sollevare eccezioni.
Invece di una lista, abbiamo fornito un intero come primo argomento, che ha sollevato
AttributeError.Nell’ultimo scenario, abbiamo fornito la lista, ma 0 come secondo argomento ha sollevato l’eccezione
ZeroDivisionErrorsotto l’istruzioneelse.Esempio di modifica file
Vediamo esempi più pratici di caricamento del file, scrittura di un testo e chiusura del file.
La funzione
file_editor()farà quanto segue:FileNotFoundErrorper la funzioneopen().write().finally.Nel primo scenario, forniamo il percorso del file e il testo.
Viene sollevata l’eccezione esterna.
Per risolvere l’eccezione “file non trovato”, dobbiamo creare un file
data.txtusando il comando Linuxecho.Dopodiché, riesegui la funzione
file_editor().Viene sollevata l’eccezione interna, poiché la funzione
write()non riesce ad aggiungere il testo.Per risolvere questo problema, dobbiamo cambiare la terza riga da
data = open(path)adata = open(path, 'a'). Ci permetterà di aggiungere nuovo testo al file.Dopo aver rieseguito la funzione, abbiamo aggiunto correttamente il testo al file.
La gestione annidata delle eccezioni non è consigliata perché rende la gestione più complessa; gli sviluppatori usano più blocchi
try-exceptper creare una gestione sequenziale semplice.Nota: puoi anche aggiungere un blocco
try-exceptannidato sotto l’istruzionetryoexcept. Dipende semplicemente dalle tue esigenze.Sollevare eccezioni in Python
Oltre a intercettare le eccezioni, puoi sollevarle deliberatamente usando la parola chiave
raise. È utile per far rispettare regole di business o la validazione degli input. Fornisce un segnale che qualcosa non va prima che causi un errore più difficile da debuggare più avanti nella catena.Per generare un’eccezione, dobbiamo usare la parola chiave
raiseseguita dal nome dell’eccezione.Esempio di ValueError sollevato
Possiamo sollevare eccezioni semplicemente aggiungendo la parola chiave raise nell’istruzione
if/else.Nell’esempio, solleviamo
ValueErrorse il valore supera 1.000. Abbiamo impostato il valore a 2.000, rendendo l’istruzioneifTRUEe sollevandoValueErrorcon un messaggio personalizzato. Il messaggio di errore personalizzato ti aiuta a individuare velocemente il problema.Esempio di eccezione sollevata
Possiamo anche sollevare una qualunque eccezione integrata di Python se la condizione è soddisfatta. Nel nostro caso, abbiamo sollevato un’eccezione generica con il messaggio di errore.
Esempio di gestione di un’eccezione sollevata
Possiamo anche creare un’eccezione personalizzata e gestirla usando il blocco
try-except.Nell’esempio, abbiamo aggiunto un caso di value error sotto l’istruzione
try.Quindi, come funzionerà? Invece di sollevare l’eccezione e terminare il programma, mostrerà il messaggio di errore che abbiamo fornito.
Questo tipo di gestione delle eccezioni ci aiuta a prepararci per errori non coperti da Python e specifici dei requisiti della tua applicazione.
Concatenazione di eccezioni con raise ... from
Oltre a sollevare eccezioni singole, puoi concatenare eccezioni usando
raise ... from. Questo preserva l’eccezione originale come contesto, rendendo i traceback molto più chiari quando un errore ne causa un altro.La parte
from eimposta l’attributo__cause__sulla nuova eccezione, così chiunque legga il traceback può vedere esattamente cosa l’ha scatenata. È particolarmente utile nelle applicazioni più grandi in cui le eccezioni attraversano più livelli di codice.Novità in Python 3.10 - 3.13 per la gestione delle eccezioni?
Alcuni sviluppi importanti sono stati aggiunti nelle versioni più recenti di Python, come la 3.10 e la 3.11, da quando questo post è stato originariamente scritto:
1. Pattern matching strutturale in Python 3.10
Python 3.10 ha introdotto il pattern matching strutturale, che può essere usato per gestire le eccezioni in modo più elegante abbinando i tipi di errore in un’istruzione
match. È particolarmente utile quando si gestiscono più tipi di eccezioni in modo più leggibile. Esempio:2. Localizzazione fine degli errori nei traceback (Python 3.11)
I traceback in Python 3.11 ora mostrano posizioni di errore precise, rendendo più semplice il debug delle eccezioni.
Prima di Python 3.11:
Con Python 3.11, i traceback evidenziano l’esatta sottoespressione che causa l’eccezione:
3. Gruppi di eccezioni ed except* (Python 3.11)
Python 3.11 ha introdotto i gruppi di eccezioni per gestire più eccezioni in un singolo blocco usando
except*. È utile per gestire codice asincrono o scenari in cui potrebbero essere sollevate più eccezioni. Esempio:4. Metodo add_note per le eccezioni (Python 3.11)
Le eccezioni ora hanno un metodo
add_note(), che consente agli sviluppatori di aggiungere note personalizzate alle eccezioni per un debug migliore. Esempio:5. PEP 654: Gestione migliore delle eccezioni annidate
Con i gruppi di eccezioni, le eccezioni annidate sono ora più facili da eseguire il debug e da gestire, specialmente in flussi di lavoro complessi come multiprocessing o attività asincrone.
6. Messaggi di errore migliorati (Python 3.12)
Python 3.12 ha proseguito uno sforzo di lunga data per rendere i messaggi di errore più specifici e utili. Ad esempio, i messaggi di
NameErrorora suggeriscono variabili con nomi simili presenti nello scope, e gli errori di attributo su tipi comuni forniscono suggerimenti più mirati:7. Traceback colorati (Python 3.13)
Python 3.13 ha introdotto per impostazione predefinita traceback colorati nell’interprete interattivo. Tipi di errore, numeri di riga e messaggi sono ora evidenziati con colori diversi, rendendo molto più veloce individuare e capire cosa è andato storto — soprattutto in traceback lunghi con più eccezioni concatenate.
Conclusione
Sia i test unitari sia la gestione delle eccezioni sono parti fondamentali della programmazione in Python che rendono il tuo codice pronto per la produzione e resistente agli errori. In questo tutorial, abbiamo visto eccezioni ed errori in Python e come gestirli. Inoltre, abbiamo visto blocchi try-except annidati più complessi e creato blocchi di eccezioni personalizzati in base alle esigenze.
Questi strumenti e meccanismi sono essenziali, ma gran parte del lavoro si svolge tramite semplici blocchi
tryeexcept. Dovetrycerca le eccezioni sollevate dal codice edexceptgestisce tali eccezioni.Se ti sembra tutto confuso e non sai da dove iniziare, completa il nostro corso Introduction to Functions in Python per capire scope, funzioni lambda e gestione degli errori. Puoi anche iscriverti al career track Python Programmer per acquisire competenze spendibili e diventare uno sviluppatore Python professionista.