如何将 traceback / sys.exc_info() 的值保存在变量中?

180 投票
5 回答
190329 浏览
提问于 2025-04-17 06:53

我想把错误的名称和错误追踪的详细信息保存到一个变量里。下面是我尝试的代码。

import sys
try:
    try:
        print x
    except Exception, ex:
        raise NameError
except Exception, er:
    print "0", sys.exc_info()[0]
    print "1", sys.exc_info()[1]
    print "2", sys.exc_info()[2]

输出结果:

0 <type 'exceptions.NameError'>
1 
2 <traceback object at 0xbd5fc8>

期望的输出结果:

0 NameError
1
2 Traceback (most recent call last):
  File "exception.py", line 6, in <module>
    raise NameError

附注:我知道可以很简单地使用 traceback 模块来做到这一点,但我想了解这里 sys.exc_info()[2] 对象的用法。

5 个回答

32

如果你想方便地获取模块和函数的名称以及行号,可以使用 traceback.extract_stack()

如果你只想要一个看起来像 traceback.print_stack() 输出的字符串,可以使用 ''.join(traceback.format_stack())

注意,即使使用了 ''.join(),你也会得到一个多行字符串,因为 format_stack() 的元素中包含了 \n。下面是输出示例。

记得要先 import traceback

这是 traceback.extract_stack() 的输出,格式化后更易阅读。

>>> traceback.extract_stack()
[
   ('<string>', 1, '<module>', None),
   ('C:\\Python\\lib\\idlelib\\run.py', 126, 'main', 'ret = method(*args, **kwargs)'),
   ('C:\\Python\\lib\\idlelib\\run.py', 353, 'runcode', 'exec(code, self.locals)'),
   ('<pyshell#1>', 1, '<module>', None)
]

这是 ''.join(traceback.format_stack()) 的输出,格式化后更易阅读。

>>> ''.join(traceback.format_stack())
'  File "<string>", line 1, in <module>\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 126, in main\n
       ret = method(*args, **kwargs)\n
   File "C:\\Python\\lib\\idlelib\\run.py", line 353, in runcode\n
       exec(code, self.locals)\n  File "<pyshell#2>", line 1, in <module>\n'
39

sys.exc_info() 会返回一个包含三个值的元组(类型、值、追踪信息)。

  1. 这里的类型是指正在处理的异常的类型
  2. 值是传递给异常类构造函数的参数
  3. 追踪信息包含了堆栈信息,比如异常发生的位置等。

例如,在下面的程序中:

try:

    a = 1/0

except Exception,e:

    exc_tuple = sys.exc_info()

如果我们打印这个元组,得到的值将是:

  1. exc_tuple[0] 的值将是 "ZeroDivisionError"
  2. exc_tuple[1] 的值将是 "integer division or modulo by zero"(传递给异常类的字符串参数)
  3. exc_tuple[2] 的值将是 "trackback object at (某个内存地址)"

以上信息也可以通过简单地将异常以字符串格式打印出来来获取。

print str(e)
252

这是我处理的方式:

>>> import traceback
>>> try:
...   int('k')
... except:
...   var = traceback.format_exc()
... 
>>> print(var)
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: invalid literal for int() with base 10: 'k'

不过,你应该看看这个traceback 的文档,因为根据你之后想怎么处理你的变量,那里可能有更合适的方法...

撰写回答