如何以编程方式检查 Python 中异常的堆栈跟踪?

发布于 2024-08-23 18:22:00 字数 259 浏览 14 评论 0原文

当Python发生异常时,你能检查堆栈吗?你能确定它的深度吗?我查看了 traceback 模块,但我不知道如何使用它。

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

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

When an exception occurs in Python, can you inspect the stack? Can you determine its depth? I've looked at the traceback module, but I can't figure out how to use it.

My goal is to catch any exceptions that occur during the parsing of an eval expression, without catching exceptions thrown by any functions it may have called. Don't berate me for using eval. It wasn't my decision.

NOTE: I want to do this programmatically, not interactively.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

〆一缕阳光ご 2024-08-30 18:22:00

traceback 就足够了 - 我认为文档描述得相当好。简化示例:

import sys
import traceback

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

traceback is enough - and I suppose that documentation describes it rather well. Simplified example:

import sys
import traceback

try:
    eval('a')
except NameError:
    traceback.print_exc(file=sys.stdout)
鲜肉鲜肉永远不皱 2024-08-30 18:22:00

您可以使用 inspect 模块,该模块具有一些用于跟踪的实用函数。查看框架对象的属性概述

You can use the inspect module which has some utility functions for tracing. Have a look at the overview of properties of the frame objects.

寄意 2024-08-30 18:22:00

我喜欢回溯模块。

您可以使用 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

I like the traceback module.

You can get a traceback object using sys.exc_info(). Then you can use that object to get a list preprocessed list of traceback entries using traceback.extract_tb(). Then you can get a readable list using traceback.format_list() as follows:

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.

See the sys Module: http://docs.python.org/library/sys.html

and the traceback Module: http://docs.python.org/library/traceback.html

南风几经秋 2024-08-30 18:22:00

您定义这样一个函数(doc here):

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 开始的迭代器。

You define such a function (doc here):

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

and call it from your modules so:

raiseErr()

The function raiseErr will print info about the place you called it.

More elaborate, you can do so:

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()

Other possibility is to define this function:

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

And call it in the place where you want the trace. If you want all the trace, make an iterator from 1 up in _getframe(1).

合约呢 2024-08-30 18:22:00

除了 AndiDog 关于 inspect 的回答之外,请注意 pdb 允许您在堆栈中上下导航,检查局部变量等。标准库 pdb.py 中的源代码可以帮助您学习如何执行此类操作。

In addition to AndiDog's answer about inspect, note that pdb lets you navigate up and down the stack, inspecting locals and such things. The source in the standard library pdb.py could be helpful to you in learning how to do such things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文