2010-03-01 64 views
17

当Python发生异常时,你可以检查堆栈吗?你能确定它的深度吗?我查看了traceback模块,但我无法弄清楚如何使用它。如何以编程方式检查Python中异常的堆栈跟踪?

我的目标是捕获在解析eval表达式期间发生的任何异常,而不捕获它可能调用的任何函数抛出的异常。不要因为使用eval而反感我。这不是我的决定。

注意:我想以编程方式执行此操作,而不是交互式操作。

回答

13

traceback就足够了 - 我想文档很好地描述了它。简单的例子:

import sys 
import traceback 

try: 
    eval('a') 
except NameError: 
    traceback.print_exc(file=sys.stdout) 
+2

我不想打印回溯。我正在检查它。这是如何告诉我在eval文本本身中还是在评估文本调用的函数中发生异常? – 2010-03-01 22:25:32

+0

如果'eval'文本错误,则会引发SyntaxError。 – 2010-03-02 09:30:56

+0

如果评估文本错误,可能会引发许多不同类型的错误。最后,我使用检查并查看回溯的深度,以查看错误是由评估原始文本引起的,还是由于它位于被调用函数的主体中。 – 2010-03-16 07:55:30

0

除了AndiDog的约inspect回答,请注意pdb让您导航向上和向下的堆栈,检查当地人和这样的事情。标准库pdb.py中的源代码可能有助于您学习如何执行此类操作。

4

我喜欢追溯模块。

您可以使用sys.exc_info()获取回溯对象。然后,您可以使用该对象获取使用traceback.extract_tb()的追溯条目列表预处理列表。然后你就可以得到使用traceback.format_list()可读名单如下:

import sys 
import traceback, inspect 

try: 
    f = open("nonExistant file",'r') 
except: 
    (exc_type, exc_value, exc_traceback) = sys.exc_info() 
    #print exception type 
    print exc_type 
    tb_list = traceback.extract_tb(sys.exc_info()[2]) 
    tb_list = traceback.format_list(tb_list) 
    for elt in tb_list: 
     print elt 
     #Do any processing you need here. 

见sys模块:http://docs.python.org/library/sys.html

和追踪模块:http://docs.python.org/library/traceback.html

1

你定义这样的函数():

def raiseErr(): 
    for f in inspect.stack(): print '-', inspect.getframeinfo(f[0]) 

并从您的模块中调用它:

raiseErr() 

函数raiseErr将打印有关您称为它的位置的信息。

更精细的,你可以这样做:

import inspect, traceback 
A = [inspect.getframeinfo(f[0]) for f in inspect.stack()] 
print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0])) 
print A[0].filename, A[0].lineno 
for f in inspect.stack(): 
    F = inspect.getframeinfo(f[0]) 
    print '-', F.filename, F.lineno, '\t', F.code_context[0].strip() 

另一种可能性是定义该功能:

def tr(): 
    print '* - '*10, 
    print sys._getframe(1).f_code.co_name 

,并调用它在你想跟踪的地方。如果你想要所有的跟踪,在_getframe(1)中从1开始迭代。