Guida a Python - Corso base - Capitolo 12: gestione delle eccezioni try-except-finally. Raise.
Capitolo 12: Gestione delle eccezioni: try-except-finally. Raise.
Le eccezioni sono eventi "anomali" (o che producono risultati tali, come la divisione per zero) che possono portare, se non opportunamente previste e gestite, alla terminazione dell'intero programma (cosa che avviene, comunque, solo se nessuno dei blocchi dell'esecuzione che racchiudono quello ove si è verificata l'eccezione consente di catturare e gestire quest'ultima; in tal caso, l'eccezione si propagherà fino al blocco più esterno, che poi equivale all'intero programma, chiudendolo, ossia terminando l'esecuzione).
Le parti di codice "sensibile" (operazioni di I/O sul file system, operazioni in rete, operazioni matematiche o sulle liste, ecc...) dovrebbero essere sempre inserite in un particolare blocco, detto try; le eccezioni (eventualmente) lanciate dalle istruzioni presenti in tale blocco potranno quindi essere gestite da altri particolari blocchi (uno o più), detti blocchi except, associati al try.
Il meccanismo di cattura e gestione delle eccezioni in Python è detto quindi try-except, ed è molto simile a quello di altri linguaggi di programmazione (come il try-catch di Java, ad esempio).
La forma base della gestione delle eccezioni in Python è quindi la seguente (attenzione ai due punti e all'indentazione):
try:
# Porzione di codice da tenere d'occhio, contenente istruzioni "sensibili"
except [eccezione1]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezione1
except [eccezione2]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezione2
# ... tutti gli except "specifici" che vogliamo, per gestire vari tipi di eccezioni ...
except[eccezioneN]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezioneN
except:
# Operazioni da eseguire se è stata lanciata un'eccezione gestibile con i blocchi except "specifici" precedenti
Ad esempio, la divisione per 0 genera errore:
>>> a = 5 >>> b = a/0 Traceback (most recent call last): File "<pyshell#213>", line 1, in <module> b = a/0 ZeroDivisionError: integer division or modulo by zero >>>
per cui per catturarla e gestirla potremo scrivere qualcosa come:
>>> a = 5 >>> try: b = a/0 except: print "Divisione per zero ! Tranquillo, non terminerò il programma: eccezione catturata e gestita !"
o, meglio ancora (visto che l'eccezione di divisione per zero è un'eccezione "nota" ed ha una sua exception "dedicata"):
>>> a = 5 >>> try: b = a/0 except ZeroDivisionError: print "Divisione per zero ! Tranquillo, non terminerò il programma: eccezione catturata e gestita !"
Esistono, quindi, molte eccezioni "note" e catturabili a parte, per essere riconosciute e gestite opportunamente; per un elenco completo, si rimanda alla documentazione ufficiale di Python.
Al blocco try-except è possibile poi aggiungere i blocchi else (eccezione non lanciata: effettua le operazioni presenti nel blocco else e vai avanti) e/o finally (ossia: esegui COMUNQUE le istruzioni presenti in tale blocco, sia che sia stata lanciata un'eccezione gestita da un blocco except, sia che non sia stata lanciata alcuna eccezione), per cui il blocco diventerà (attenzione ai due punti e all'indentazione !!!):
try:
# Porzione di codice da tenere d'occhio, contenente istruzioni "sensibili"
except [eccezione1]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezione1
except [eccezione2]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezione2
# ... tutti gli except "specifici" che vogliamo, per gestire vari tipi di eccezioni ...
except[eccezioneN]:
# Operazioni da effettuare se è stata lanciata un'eccezione di tipo eccezioneN
except:
# Operazioni da eseguire se è stata lanciata un'eccezione gestibile con i blocchi except "specifici" precedenti
else:
# Operazioni da eseguire se non sono state lanciate eccezioni
finally:
# Operazioni da eseguire COMUNQUE
In Python è possibile, inoltre, lanciare volutamente un'eccezione, ad esempio per gestire un evento particolare o per passare il controllo ad un blocco più esterno (questo avviene lanciando un'eccezione senza parametri); per lanciare un'eccezione, utilizzare l'istruzione:
raise [eventuale nome dell'eccezione [, eventuale messaggio da mostrare a video]]
Esempi:
>>> raise Traceback (most recent call last): ** IDLE Internal Exception: File "C:\Python25\lib\idlelib\run.py", line 288, in runcode exec code in self.locals File "C:\Python25\lib\idlelib\run.py", line 87, in main seq, request = rpc.request_queue.get(block=True, timeout=0.05) File "C:\Python25\lib\Queue.py", line 173, in get raise Empty Empty
>>> raise ZeroDivisionError Traceback (most recent call last): File "<pyshell#219>", line 1, in <module> raise ZeroDivisionError ZeroDivisionError
>>> raise ZeroDivisionError, 'Ciao !' Traceback (most recent call last): File "<pyshell#220>", line 1, in <module> raise ZeroDivisionError, 'Ciao !' ZeroDivisionError: Ciao !
>>>
|