如何获取在Python中捕获的异常的名称?


122

如何获得在Python中引发的异常的名称?

例如,

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

例如,我捕获了多个(或所有)异常,并想在错误消息中打印异常的名称。


3
为什么您认为需要这个?为什么不赶上一个更具体的例外(例如except NameError:)?

7
我有几种情况,我想捕获所有异常(或它们的列表),并想在错误消息中打印出异常的名称。
Rob Bednark

1
您可能想查看标准库的traceback模块,该模块的功能可以很好地格式化异常和回溯。
Blckknght 2014年

1
@delnan当您测试某个函数是否按编程引发异常时,会出现这种情况
gokul_uf

我需要这样的代码来干燥一些代码:我所调用的方法可以引发几个异常,每个异常都用自己的except语句处理,但是每种情况下的日志条目都非常相似。
亚当·卡洛尔

Answers:


223

以下是获取异常类名称的几种不同方法:

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

例如,

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

6

这行得通,但似乎必须有一种更简单,更直接的方法?

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
替换except Exception as exception为您要捕获的异常类型,即except NameError as exception
Maciej Gol 2013年

8
我不想捕获事先已知的特定异常。我想抓住所有例外。
Rob Bednark

3

您也可以使用sys.exc_info()exc_info()返回3个值:类型,值,回溯。关于文档: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

如果您想要完全限定的类名(例如,sqlalchemy.exc.IntegrityError而不是仅使用IntegrityError),则可以使用下面的函数,该函数是我从MB对另一个问题的出色回答(我只是重命名了一些变量以适合自己的口味)而来:

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__

例:

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

此处的其他答案非常适合用于探索目的,但是如果主要目标是记录异常(包括异常的名称),则可以考虑使用logging.exception而不是print?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.