Come ottenere il nome dell'eccezione catturata in Python?


122

Come posso ottenere il nome di un'eccezione che è stata sollevata in Python?

per esempio,

try:
    foo = bar
except Exception as exception:
    name_of_exception = ???
    assert name_of_exception == 'NameError'
    print "Failed with exception [%s]" % name_of_exception

Ad esempio, sto rilevando più (o tutte) eccezioni e voglio stampare il nome dell'eccezione in un messaggio di errore.


3
Perché pensi di aver bisogno di questo? Perché non cogliere un'eccezione più concreta (ad esempio except NameError:) per cominciare?

7
Ho un paio di scenari in cui voglio catturare tutte le eccezioni (o un elenco di esse) e voglio stampare il nome dell'eccezione in un messaggio di errore.
Rob Bednark

1
Potresti voler controllare il tracebackmodulo della libreria standard , che ha funzioni che fanno una bella formattazione di eccezioni e traceback.
Blckknght

1
@delnan questa situazione si verifica quando stai testando se una funzione sta sollevando un'eccezione come programmato
gokul_uf

Avevo bisogno di qualcosa di simile per DRY su un po 'di codice: diverse eccezioni possono essere sollevate dal metodo che sto chiamando, ognuna viene gestita con la propria exceptistruzione, ma la voce di log è molto simile in ogni caso.
Adam Carroll

Risposte:


224

Ecco alcuni modi diversi per ottenere il nome della classe dell'eccezione:

  1. type(exception).__name__
  2. exception.__class__.__name__
  3. exception.__class__.__qualname__

per esempio,

try:
    foo = bar
except Exception as exception:
    assert type(exception).__name__ == 'NameError'
    assert exception.__class__.__name__ == 'NameError'
    assert exception.__class__.__qualname__ == 'NameError'

6

Funziona, ma sembra che ci debba essere un modo più semplice e diretto?

try:
    foo = bar
except Exception as exception:
    assert repr(exception) == '''NameError("name 'bar' is not defined",)'''
    name = repr(exception).split('(')[0]
    assert name == 'NameError'

4
Sostituisci except Exception as exceptioncon il tipo di eccezione che desideri rilevare, ad es except NameError as exception.
Maciej Gol

8
Non voglio cogliere particolari eccezioni note in anticipo. Voglio catturare tutte le eccezioni.
Rob Bednark,

3

Puoi anche usare sys.exc_info(). exc_info()restituisce 3 valori: tipo, valore, traceback. Sulla documentazione: https://docs.python.org/3/library/sys.html#sys.exc_info

import sys

try:
    foo = bar
except Exception:
    exc_type, value, traceback = sys.exc_info()
    assert exc_type.__name__ == 'NameError'
    print "Failed with exception [%s]" % exc_type.__name__

1

Se vuoi il nome completo della classe (ad esempio sqlalchemy.exc.IntegrityErrorinvece del solo IntegrityError), puoi usare la funzione di seguito, che ho preso dalla fantastica risposta di MB a un'altra domanda (ho appena rinominato alcune variabili per soddisfare i miei gusti):

def get_full_class_name(obj):
    module = obj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return obj.__class__.__name__
    return module + '.' + obj.__class__.__name__

Esempio:

try:
    # <do something with sqlalchemy that angers the database>
except sqlalchemy.exc.SQLAlchemyError as e:
    print(get_full_class_name(e))

# sqlalchemy.exc.IntegrityError

0

Le altre risposte qui sono ottime per scopi di esplorazione, ma se l'obiettivo principale è registrare l'eccezione (incluso il nome dell'eccezione), forse prendere in considerazione l'utilizzo di logging.exception invece di print?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.