You are here: Partenza > Dive Into Python > Una struttura orientata agli oggetti > Gestire le eccezioni | << >> | ||||
Dive Into PythonPython per programmatori esperti |
Come molti linguaggi orientati agli oggetti, Python consente la manipolazione delle eccezioni tramite i blocchi try...except.
Python usa try...except per gestire le eccezioni e raise per generarle. Java e C++ usano try...catch per gestirle e throw per generarle. |
Se conoscete già tutto riguardo le eccezioni, potete saltare questa sezione. Se siete rimasti bloccati programmando in un linguaggio minore che non ha la gestione delle eccezioni, o avete usato un linguaggio vero, ma senza usare le eccezioni, questa sezione è molto importante.
Le eccezioni sono ovunque in Python; virtualmente ogni modulo nella libreria standard di Python le usa e Python stesso le solleva in molte differenti circostanze. Le avete già viste spesso in questo libro.
In ognuno di questi casi, stavamo semplicemente giocando intorno all'IDE di Python: si incappa in un errore, l'eccezione viene stampata (a seconda del vostro IDE, in un intenzionale e stonante ombra di rosso) e niente più. Questa viene chiamata eccezione non gestita; quando l'eccezione veniva sollevata, non c'era codice che la notasse esplicitamente e se ne occupasse, perciò tutto proseguiva secondo il comportamento predefinito di Python, stampando alcune informazioni di debug e terminando il programma. Nell'IDE questo non è un grosso problema, ma se accade mentre il vostro programma Python reale è in esecuzione, l'intero programma va incontro ad un'improvvisa e poco piacevole interruzione. [6]
Un'eccezione non deve tuttavia comportare il crash dell'intero programma. Le eccezioni, quando sollevate, possono essere gestite. Qualche volta un'eccezione è autentica perché c'è un difetto nel vostro codice (come l'accesso ad una variabile inesistente), spesso però un'eccezione è qualcosa che avevate previsto. Se, ad esempio, state aprendo un file, questi potrebbe non esistere; se vi state connettendo ad un database, potrebbe non essere disponibile o potreste non avere i necessari requisiti di sicurezza per accedervi. Se sapete che una linea di codice potrebbe sollevare un'eccezione, dovreste gestirla usando un blocco try...except.
>>> fsock = open("/notthere", "r") Traceback (innermost last): File "<interactive input>", line 1, in ? IOError: [Errno 2] No such file or directory: '/notthere' >>> try: ... fsock = open("/notthere") ... except IOError: ... print "The file does not exist, exiting gracefully" ... print "This line will always print" The file does not exist, exiting gracefully This line will always print
Le eccezioni possono sembrare ostiche (dopotutto, se non catturate l'eccezione, il vostro intero programma terminerà), ma considerate l'alternativa. Vorreste veramente ottenere un oggetto file riferito ad un file non esistente? Dovreste in ogni caso controllarne la validità e se ve ne dimenticate, il vostro programma vi darebbe strani errori da qualche parte nelle linee seguenti e voi sareste costretti a ricontrollare l'intero codice, alla ricerca della causa del problema. Sono sicuro che lo avete già fatto; non è divertente. Con le eccezioni, gli errori vengono rilevati immediatamente e potete risolvere il problema alla radice, gestendoli in modo standard.
Ci sono molti altri usi delle eccezioni oltre alla gestione degli errori. Un uso comune nella libreria standard Python consiste nel provare ad importare un modulo e poi provare se funzioni o meno. Importare un modulo che non esiste causa il sollevamento dell'eccezione ImportError. Potete usarla per definire molteplici livelli di funzionalità, basati su quali moduli sono disponibili a run-time, o per supportare molteplici piattaforme (dove il codice specifico per ogni piattaforma è suddiviso in moduli differenti).
Potete inoltre definire le vostre stesse eccezioni, creando una classe che eredita dalla classe built-in Exception e sollevare le vostre eccezioni tramite il comando raise. Questo va al di fuori dallo scopo di questa sezione ma leggete gli ulteriori paragrafi se siete interessati.
Questo codice proviene dal modulo getpass, un modulo wrapper per ottenere password dagli utenti. Ottenere una password è significativamente differente da piattaforme UNIX, Windows e Mac OS, ma questo codice incapsula tutte differenze.
# Bind the name getpass to the appropriate function try: import termios, TERMIOS except ImportError: try: import msvcrt except ImportError: try: from EasyDialogs import AskPassword except ImportError: getpass = default_getpass else: getpass = AskPassword else: getpass = win_getpass else: getpass = unix_getpass
[6] O, come alcuni pignoli farebbero notare, il vostro programma effettuerebbe un'azione illegale. Qualunque.
<< Funzioni private |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | |
Oggetti file >> |