Python Language Sollevamento e gestione delle eccezioni


Esempio

Questa è la sintassi di Python 2, nota le virgole , raise e except linee:

Python 2.x 2.3
try:
    raise IOError, "input/output error"
except IOError, exc:
    print exc

In Python 3, la sintassi , viene eliminata e sostituita da parentesi e la parola chiave as :

try:
    raise IOError("input/output error")
except IOError as exc:
    print(exc)

Per compatibilità con le versioni precedenti, la sintassi di Python 3 è disponibile anche in Python 2.6, quindi dovrebbe essere utilizzata per tutti i nuovi codici che non devono essere compatibili con le versioni precedenti.


Python 3.x 3.0

Python 3 aggiunge anche il concatenamento delle eccezioni , in cui è possibile segnalare che qualche altra eccezione è stata la causa di questa eccezione. Per esempio

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from e

L'eccezione sollevata __cause__ except è di tipo DatabaseError , ma l'eccezione originale è contrassegnata come l'attributo __cause__ di tale eccezione. Quando viene visualizzato il traceback, l'eccezione originale verrà visualizzata anche nel traceback:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

Se lanci un blocco except senza concatenamento esplicito:

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}')

Il traceback è

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
Python 2.x 2.0

Nessuno dei due è supportato in Python 2.x; l'eccezione originale e il suo traceback saranno persi se viene sollevata un'altra eccezione nel blocco eccetto. Il seguente codice può essere utilizzato per la compatibilità:

import sys
import traceback

try:
    funcWithError()
except:
    sys_vers = getattr(sys, 'version_info', (0,))
    if sys_vers < (3, 0):
        traceback.print_exc()
    raise Exception("new exception")
Python 3.x 3.3

Per "dimenticare" l'eccezione precedentemente generata, usa raise from None

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from None

Ora il traceback sarebbe semplicemente

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

Oppure per renderlo compatibile con entrambi i Python 2 e 3 è possibile utilizzare il pacchetto sei in questo modo:

import six
try:
    file = open('database.db')
except FileNotFoundError as e:
    six.raise_from(DatabaseError('Cannot open {}'), None)