Comment obtenir le nom de l'exception qui a été capturée en Python?


122

Comment puis-je obtenir le nom d'une exception qui a été déclenchée en Python?

par exemple,

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

Par exemple, j'attrape plusieurs exceptions (ou toutes) et je souhaite imprimer le nom de l'exception dans un message d'erreur.


3
Pourquoi pensez-vous que vous en avez besoin? Pourquoi ne pas saisir une exception plus concrète (par exemple except NameError:) pour commencer?

7
J'ai quelques scénarios dans lesquels je veux attraper toutes les exceptions (ou une liste d'entre elles) et que je veux imprimer le nom de l'exception dans un message d'erreur.
Rob Bednark

1
Vous voudrez peut-être consulter le tracebackmodule de la bibliothèque standard , qui a des fonctions qui font un bon formatage des exceptions et des retraits.
Blckknght

1
@delnan cette situation se produit lorsque vous testez si une fonction lève une exception comme programmé
gokul_uf

J'avais besoin de quelque chose comme ça pour SÉCHER du code: plusieurs exceptions peuvent être déclenchées par la méthode que j'appelle, chacune étant gérée avec sa propre exceptinstruction, mais l'entrée de journal est très similaire dans chaque cas.
Adam Carroll

Réponses:


226

Voici quelques méthodes différentes pour obtenir le nom de la classe de l'exception:

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

par exemple,

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

6

Cela fonctionne, mais il semble qu'il doit y avoir un moyen plus simple et plus direct?

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
Remplacez except Exception as exceptionpar le type d'exception que vous souhaitez attraper, c'est-à-dire except NameError as exception.
Maciej Gol

8
Je ne veux pas attraper des exceptions particulières connues à l'avance. Je veux attraper toutes les exceptions.
Rob Bednark

4

Vous pouvez également utiliser sys.exc_info(). exc_info()renvoie 3 valeurs: type, valeur, traceback. Sur la documentation: 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

Si vous voulez le nom de classe complet (par exemple sqlalchemy.exc.IntegrityErrorau lieu de juste IntegrityError), vous pouvez utiliser la fonction ci-dessous, que j'ai tirée de la réponse impressionnante de MB à une autre question (j'ai simplement renommé certaines variables selon mes goûts):

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__

Exemple:

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

# sqlalchemy.exc.IntegrityError

1

Les autres réponses ici sont excellentes à des fins d'exploration, mais si l'objectif principal est de consigner l'exception (y compris le nom de l'exception), envisagez peut-être d'utiliser logging.exception au lieu de print?

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.