martedì 11 dicembre 2012

Gestione delle eccezioni

Errare humanum est, si dice. Non so voi ma io sono molto umano. E gli utenti che conosco sono ancora più umani di me. Bisogna fare qualcosa, prevedere che qualcosa possa andare storto.
Prendi questo esempio, semplicissimo (radq0.py):



#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys, math

if len(sys.argv) == 1:
    print 'Uso:', sys.argv[0], 'numero'
    sys.exit(1)

num = float(sys.argv[1])
print num, math.sqrt(num)
Sembra tutto OK, vero?
No! guarda qui:
No, non va, bisogna gestire le condizioni di errore. Siccome "errore" a qualcuno non piace (gli ingegneri, i politici, i preti, le persone normali insomma) chiamiamole eccezioni.

Il metodo che usiamo è di proteggere la parte di codice a rischio di errore, cioè volevo dire a rischiosa (radq1.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys, math

try:
    num = float(sys.argv[1])
    print num, math.sqrt(num)
except:
    print 'OPS! qualcosa è andato storto'
    print 'Uso:', sys.argv[0], 'numero'
OK! meglio del previsto, riusciamo a catturare tutte le eccezioni con una condizione sola. In genere non siamo così fortunati e di try ne dovremo mettere diversi ma il concetto dovrebbe essere chiaro.

Un caso tipico si trova nella gestione dei file (gestfile.py):
#!/usr/bin/python
# -*- coding: utf-8 -*-

nomeOK = 'radq1.py'
nomeERR = 'manca.py'
outOK = 'outOK.txt'
outERR = '/err/'

def leggi(nome):
    try:
        inp = open(nome, 'r')
        txt = inp.read()
        inp.close()
    except:
        print "Errore nell'apertura di", nome
        txt = ''
    return txt

def scrivi(nome, txt):
    try:
        outp = open(nome, 'w')
        outp.write(txt)
        outp.close()
    except:
        print "Errore nell'apertura di", nome

# main
print 'caso di', nomeOK, 'e', outOK
txt = leggi(nomeOK)
scrivi(outOK, txt)

print
print 'caso di', nomeERR, 'e', outERR
txt = leggi(nomeERR)
scrivi(outERR, txt)
OK? Si potrebbe fare anche meglio, certo. Per esempio leggi() potrebbe tornare una tupla con il primo elemento un valore booleano indicante il successo cosicchè la scrivi() verrebbe chiamata solo se la lettura è andata a buon fine. In alternativa si potrebbe controllare se len(txt) > 0, questo è il modo vecchio (ma sempre valido).
Lo facciamo? No, lasciato come esercizio.

Juhan

L'indice di Mission Python è qui!!!

Nessun commento:

Posta un commento