Python 如何在变量中保存traceback/sys.exc_info()值?
我想将错误名称和回溯详细信息保存到一个变量中。这是我的尝试Python 如何在变量中保存traceback/sys.exc_info()值?,python,python-2.7,exception,Python,Python 2.7,Exception,我想将错误名称和回溯详细信息保存到一个变量中。这是我的尝试 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 &
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
0
1.
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
0名称错误
1.
2回溯(最近一次呼叫最后一次):
文件“exception.py”,第6行,在
引发名称错误
另外,我知道使用回溯模块可以很容易地做到这一点,但我想知道sys.exc_info()[2]对象在这里的用法。我就是这样做的:
>>> 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'
导入回溯
>>>尝试:
... int('k')
... 除:
... var=traceback.format_exc()
...
>>>打印变量
回溯(最近一次呼叫最后一次):
文件“”,第2行,在
ValueError:基数为10的int()的文本无效:“k”
但是,您应该查看,因为您可能会发现有更合适的方法,这取决于您以后希望如何处理变量…如果您希望方便地访问模块和函数名以及行号,请使用
回溯。extract_stack()
如果您只需要一个类似于traceback.print\u stack()
输出的字符串,请使用'.join(traceback.format\u stack())
注意,即使使用“”。join()
也会得到多行字符串,因为format\u stack()
的元素包含\n
。请参见下面的输出
记住导入回溯
这是traceback.extract\u 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())
' 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'
sys.exc_info()返回一个包含三个值(类型、值、回溯)的元组
try:
a = 1/0
except Exception,e:
exc_tuple = sys.exc_info()
现在,如果我们打印元组,值将如下所示
print str(e)
该对象可用作
异常中的参数。使用\u traceback()
函数:
except Exception as e:
tb = sys.exc_info()
print(e.with_traceback(tb[2]))
从异常处理程序中取出异常对象或回溯对象时要小心,因为这会导致循环引用,并且
gc.collect()
将无法收集。这似乎是ipython/jupyter笔记本环境中的一个特殊问题,在这个环境中,回溯对象没有在正确的时间被清除,甚至在最后
部分中显式调用gc.collect()
也没有任何作用。如果您有一些大型对象无法回收其内存,这将是一个巨大的问题(例如,CUDA内存不足异常,此解决方案需要完全重新启动内核才能恢复)
通常,如果要保存回溯对象,需要将其从对locals()
的引用中清除,如下所示:
import sys, traceback, gc
type, val, tb = None, None, None
try:
myfunc()
except:
type, val, tb = sys.exc_info()
traceback.clear_frames(tb)
# some cleanup code
gc.collect()
# and then use the tb:
if tb:
raise type(val).with_traceback(tb)
对于jupyter notebook,您必须至少在异常处理程序中执行此操作:
try:
myfunc()
except:
type, val, tb = sys.exc_info()
traceback.clear_frames(tb)
raise type(val).with_traceback(tb)
finally:
# cleanup code in here
gc.collect()
使用Python3.7进行测试
p、 ipython或jupyter notebook env的问题在于它有
%tb
魔力,可以保存回溯并在以后的任何时候提供。因此,在笔记本退出之前,参与回溯的所有帧中的任何locals()
都不会被释放,或者另一个异常将覆盖以前存储的回溯。这是非常有问题的。它不应在不清洁其框架的情况下存储回溯。已提交修复程序。我正在寻找一种不使用回溯模块的方法。是否有某种方法可以从该对象引用打印回溯详细信息?sys.exc_info()[2]是的,这就是为什么我认为我们可以像sys.exc_info()[2]那样进行格式化,但这不起作用。。因此,我想知道如何从追溯对象sys.exc_info()[2]中提取值。有什么想法吗?sys.exc_info()[2].tb_text给出follow error->AttributeError:“traceback”对象没有属性“tb_text”@dragosrsupercool-sys.exc_info()[2].tb_frame.f_code.co_name[3]
,但这毫无意义。。。如果标准库中有一个名为traceback
的模块,那么它是有原因的…)@codersofdarktraceback.format\u exception(*sys.exc\u info())
就是这样做的。但这在功能上相当于traceback.format_exc()
。您是否尝试打印sys.exc_info()[x]。\uu str_uu()?您可能误解了程序中发生的事情:您所称的“sys.exc_info()[2]对象”是回溯对象的一个实例(=您已经在使用回溯模块)。现在,您可以在不使用回溯模块中的helper函数的情况下操作该对象,但这不会改变您仍在使用它的事实。:)所以@mac请帮助我使用helper函数或不使用helper函数来访问此对象的值。@dragosrsupercool-正如我在下面的回答中提到的,您应该查看。我提供了一个如何以文本方式检索数据的示例,但该对象还有其他方法,允许您提取异常名称、代码行等。。。正确的答案取决于你想如何在事后操纵这个值…我的另一个问题可能有助于说明细节-通过链接!对于罐装字符串,标准库回溯模块似乎还可以。如果您想获得详细信息,请阅读源代码()以了解更多信息。对于Python3,exc_tuple[1](aka value)是异常的实例,而不是“作为参数传递的字符串”。请看:它不应该是“例外情况除外,如e:”?