|
La cosa interessante è che le misure di gestione possono essere "a grana grossa" (ovvero: in caso di QUALUNQUE ERRORE fai così…) o a grana fine (se è un errore di I/O fai così, se è un errore di calcolo fai in quest'altro modo...). Le eccezioni vengono poi catturate, utilizzando un sistema a filtro e distinguendole per tipo. Un filtro che può essere raffinato quando si vuole, ma non si costringe a controllare l'istruzione per istruzione quello che succede.
Vediamo un esempio in cui proviamo a aprire un file e a leggere il suo contenuto,gestendo eventuali errori. Supponiamo di avere un modulo "legginum.py" che contiene la funzione "legginum":
def legginum(arg):
try:
f = open(arg, "r")
x = int(f.readline())
except IOError, inst:
print "cannot open", inst
except:
print "unexpected"
else:
print x
Questo programma legge un file che si aspetta contenga un numero intero. Se lo trova lo stampa. Ma varie cose possono andar storte: per esempio il file potrebbe non esserci, o non contenere un numero.
Come si può notare, il codice di lettura del file è contenuto in una istruzione "try", che sottopone a controllo di eccezioni il codice che fa il lavoro.
Proviamo adesso ad utilizzarlo con un file che contiene effettivamente un numero:
>>> from legginum import legginum
>>> legginum("num.txt")
77
Tutto ok. Ma se adesso proviamo a dare in pasto al programma un file che non c'è, questo errore è previsto e infatti viene gestito:
>>> legginum("nofile.txt")
cannot open [Errno 2] No such file or directory: 'nofile.txt'
Se adesso proviamo con un file che non contiene un numero, otteniamo un errore "imprevisto" (almeno per il codice che abbiamo scritto), e il "paracadute" (ovvero la clausola di cattura tutti gli errori generici) interviene scrivendo "unexpected".
>>> legginum("nonum.txt")
unexpected
|