Eccezioni

Le eccezioni sono errori rilevati da Python durante l’esecuzione del programma. Quando l’interprete incontra una situazione eccezionale, come ad esempio cercando di dividere un numero per 0 o tentare di accedere a un file inesistente, Phyton genera o lancia un’eccezione, informando all’utente che esiste qualche problema.
Se l’eccezione non si cattura, il flusso di esecuzione si ferma e visualizza le informazioni associate all’eccezione sulla console, in modo che il programmatore possa risolvere il problema.
Esempio
Ecco un piccolo programma che genera un’eccezione quando si tenta di dividere 1 per 0.
		def divisione(a, b):
		    return a / b
		def calcolare():
		    divisione(1, 0)
		
		calcolare()
Se si esegue si ottiene il seguente messaggio di errore:
		Traceback (most recent call last):
		File "<pyshell#78>", line 1, in <module>
			calcolare()
		File "<pyshell#77>", line 2, in calcolare
			divisione(1, 0)
		File "<pyshell#74>", line 2, in divisione
			return a / b
		ZeroDivisionError: integer division or modulo by zero
La prima cosa che si mostra è la traccia dello stack o traceback, che consiste in un elenco con le chiamate che hanno causato l’eccezione. Come mostrato nello stack, l’errore è stato causato dalla chiamata calcolare() sulla linea 1, che a sua volta ha richiamato divisione(1, 0) sulla linea 2 ed infine per l’esecuzione della sentenza a / b sulla linea 2 di divisione.
Vediamo ora il tipo di eccezione, ZeroDivisionError, insieme a una descrizione dell’errore: “integer division or modulo by zero” (modulo o divisione intera per zero).
In Python viene utilizzato una costruzione try-except per catturare e gestire le eccezioni. Il blocco try (prova) definisce il frammento di codice in cui crediamo potrebbe causare un’eccezione. Il blocco except (eccezione) consente di specificare il trattamento che deve essere effettuato se tale eccezione si verifica. Molte volte il nostro trattamento di eccezione è semplicemente quello di stampare un messaggio amichevole all’utente, altre volte ci interessa registrare gli errori e, occasionalmente, possiamo stabilire una strategia per risolvere il problema.
Nell’esempio seguente si tenta di creare un oggetto f del tipo file. Se il file passato come argomento non esiste, viene lanciato un’eccezione di tipo IOError, che catturiamo grazie al nostro try-except.
		try:
		    f = file("mio_file.txt")
		except:
		    print "Il file non esiste"
Python consente di utilizzare vari except in un unico blocco try, in modo che possiamo dare un trattamento diverso per il tipo di eccezione. Si tratta di buone pratiche, ed è facile come definire il nome del tipo dopo l’except.
		try:
		    num = int("3a")
		    print non_esiste
		except NameError:
		    print "La variabile non esiste"
		except ValueError:
		    print "Il valore non è un numero"
Quando viene generata un’eccezione nel blocco try, si cerca in tutte le except, un gestore adatto al tipo di errore che si è verificato. Se non viene trovato, l’eccezione viene propagata.
Possiamo fare anche che uno stesso except serva per trattare più di un’eccezione utilizzando una tupla per elencare i tipi di errori che vogliamo che tratti il blocco:
		try:
		    num = int("3a")
		    print non_esiste
		except (NameError, ValueError):
		    print "Si è verificato un errore"
La costruzione try-except può avere anche una clausola else, che definisce un frammento di codice da eseguire solo se non vi è stata alcuna eccezione nel try.
		try:
		    num = 33
		except:
		    print "Si è verificato un errore!"
		else:
		    print "Va tutto bene!"
C’è anche una clausola finally viene sempre eseguito, anche se non c’è un’eccezione. Questa clausola viene spesso utilizzata, tra l’altro, per compiti di pulizia.
		try:
		    z = x / y
		except ZeroDivisionError:
		    print "Divisione per zero"
		finally:
		    print "…pulizia…"
È interessante notare che anche i programmatori possono creare e lanciare le proprie eccezioni personalizzate. È sufficiente creare una classe che eredita da Exception o una delle sue figlie e lanciarla con raise.
		class MioErrore(Exception):
		    def __init__(self, valore):
		        self.valore = valor
		    def __str__(self):
		        return "Errore " + str(self.valore)
		try:
		    if risultato > 20:
		        raise MioErrore(33)
		except MioErrore, e:
		    print e
Infine, di seguito sono elencate le eccezioni di riferimento disponibili di default e la classe che ne deriva tra le parentesi.
Eccezioni di riferimento disponibili di default
  • BaseException: Classe da cui ereditano tutte le eccezioni.
  • Exception(BaseException): Super classe di tutte le eccezioni che non sono in uscita.
  • GeneratorExit(Exception): Si chiede di uscire da un generatore.
  • StandardError(Exception): Classe base per tutte le eccezioni che non hanno nulla a che fare con l’uscita dall’interprete.
  • ArithmeticError(StandardError): Classe di base per errori di aritmetica.
  • FloatingPointError(ArithmeticError): Errore in un’operazione con la virgola mobile.
  • OverflowError(ArithmeticError): Risultato troppo grande per essere rappresentato.
  • ZeroDivisionError(ArithmeticError): Lanciata quando il secondo argomento di un’operazione di una divisione o di un modulo è 0.
  • AssertionError(StandardError): Fallita la condizione di una dichiarazione assertiva.
  • AttributeError(StandardError): Attributo non trovato.
  • EOFError(StandardError): Si è tentato di leggere oltre la fine del file.
  • EnvironmentError(StandardError): Classe padre degli errori relativi al input/output.
  • IOError(EnvironmentError): Errore in un’operazione di input/output.
  • OSError(EnvironmentError): Errore in una chiamata al sistema.
  • WindowsError(OSError): Errore in una chiamata al sistema Windows.
  • ImportError(StandardError): Impossibile trovare il modulo o l’elemento del modulo che si voleva importare.
  • LookupError(StandardError): Classe padre per gli errori di accesso.
  • IndexError(LookupError): L’indice della sequenza è al di fuori dall’intervallo possibile.
  • KeyError(LookupError): La chiave non esiste.
  • MemoryError(StandardError): Non c’è memoria sufficiente.
  • NameError(StandardError): Non si è trovato nessun elemento con quel nome.
  • UnboundLocalError(NameError): Il nome non è associato ad alcuna variabile.
  • ReferenceError(StandardError): L’oggetto non ha alcun riferimento forte puntato ad esso.
  • RuntimeError(StandardError): Errore di runtime non specificato.
  • NotImplementedError(RuntimeError): Questo metodo o funzione non è implementato.
  • SyntaxError(StandardError): Classe padre per errori di sintassi.
  • IndentationError(SyntaxError): Errore d’indentazione nel file.
  • TabError(IndentationError): Errore dovuto alla mischia di spazi e tabulazioni.
  • SystemError(StandardError): Errore interno dell’interprete.
  • TypeError(StandardError): Tipo di argomento inappropriato.
  • ValueError(StandardError): Valore di argomento inappropriato.
  • UnicodeError(ValueError): Classe padre per errori relativi all’unicode.
  • UnicodeDecodeError(UnicodeError): Errore di decodificazione unicode.
  • UnicodeEncodeError(UnicodeError): Errore di codificazione unicode.
  • UnicodeTranslateError(UnicodeError): Errore di traduzione unicode.
  • StopIteration(Exception): Utilizzato per indicare la fine del iteratore.
  • Warning(Exception): Classe padre per gli avvisi.
  • DeprecationWarning(Warning): Classe padre per gli avvisi relativi a caratteristiche deprecate.
  • FutureWarning(Warning): Avviso. La semantica della costruzione cambierà in futuro.
  • ImportWarning(Warning): Avviso di possibili errori durante l’importazione.
  • PendingDeprecationWarning(Warning): Avviso sulle caratteristiche che si contrassegneranno come obsoleti in un prossimo futuro.
  • RuntimeWarning(Warning): Avviso suoi comportamenti dubbi in fase di esecuzione.
  • SyntaxWarning(Warning): Avviso sulla sintassi dubbia.
  • UnicodeWarning(Warning): Avviso sui problemi connessi con Unicode, in particolare con problemi di conversione.
  • UserWarning(Warning): Classe padre per gli annunci creati dal programmatore.
  • KeyboardInterrupt(BaseException): Il programma è stato interrotto dall’utente.
  • SystemExit(BaseException): Richiesta dell’interprete di abbandonare l’esecuzione.

  • Similari
    Overloading di metodi in Java
    12% Java
    Un metodo overload viene utilizzato per riutilizzare il nome di un metodo ma con argomenti diversi, opzionalmente con un differente tipo di ritorno. [expand title=”Regole per overload” startwrap=”” endwrap=”” excerpt=”⤽” s…
    Modi di fare e di non fare in Python
    11% Python
    Questo documento può essere considerato un compagno del tutorial di Python. Viene illustrato come utilizzare Python, e quasi ancora più importante, come non usare Python. [expand title=”Costrutti del linguaggio che non dov…
    redirect 301 usando mod_alias
    9% Server
    mod_alias è fondamentalmente la versione più semplice di mod_rewrite. Non può fare le cose che fa mod_rewrite, ad esempio modificare la stringa di query. Per eseguire reindirizzamenti nel server web Apache è possibile di u…
    Installare Python e Django su Windows
    8% Django
    Quando ci riferiamo allo sviluppo web con Python, la prima cosa che viene in mente è usare un qualche framework. Il più famoso e utilizzato da tutti è il Django, ma non è l’unico. Ci sono Pylons, Grok, TurboGears e Zope: t…
    Metodi magici e costanti predefinite in PHP
    8% Php
    PHP fornisce un insieme di costanti predefinite e metodi magici per i nostri programmi. A differenza delle normali costanti i quali si impostano con define(), il valore delle costanti predefinite o speciali dipendono da do…