在python中查找源异常的模块名

Find module name of the originating exception in Python

例子:

1
2
3
4
5
6
>>> try:
...    myapp.foo.doSomething()
... except Exception, e:
...    print 'Thrown from:', modname(e)

Thrown from: myapp.util.url

在上述的例子,实际的异常是在url.py thrown MyApp的/有用/模块。有一__name__)的方式是对模块?

我的意图是在logging.getLogger使用这个函数。


这应该有效:

1
2
3
4
5
6
7
8
import inspect

try:
    some_bad_code()
except Exception, e:
    frm = inspect.trace()[-1]
    mod = inspect.getmodule(frm[0])
    print 'Thrown from', mod.__name__

编辑:stephan202提到了一个角落案例。在这种情况下,我认为我们可以默认为文件名。

1
2
3
4
5
6
7
8
9
import inspect

try:
    import bad_module
except Exception, e:
    frm = inspect.trace()[-1]
    mod = inspect.getmodule(frm[0])
    modname = mod.__name__ if mod else frm[1]
    print 'Thrown from', modname

问题是,如果模块没有被加载(因为在读取该文件中的代码时引发了异常),那么inspect.getmodule调用将返回none。所以,我们只使用有问题的帧引用的文件名。(感谢您指出这一点,Stephan202!)


您可以使用回溯模块和sys.exc_info()以编程方式获取回溯:

1
2
3
4
5
6
try:
    myapp.foo.doSomething()
except Exception, e:
    exc_type, exc_value, exc_tb = sys.exc_info()
    filename, line_num, func_name, text = traceback.extract_tb(exc_tb)[-1]
    print 'Thrown from: %s' % filename


我有一个关于crashkit如何从公司博客"python stack trace saga"上的python堆栈跟踪计算类名和包名的故事。包括工作代码。


python的日志记录包已经支持这一点——检查文档。您只需在格式字符串中指定%(module)s。但是,这将为您提供捕获异常的模块——不一定与引发异常的模块相同。当然,溯源可以为您提供引发异常的精确位置。


这应该可以做到:

1
2
3
4
5
import inspect
def modname():
    t=inspect.trace()
    if t:
        return t[-1][1]