【发布时间】:2013-08-29 09:37:36
【问题描述】:
我试图在 except: 块内引发异常,但解释器试图提供帮助并“强制”打印堆栈跟踪。有没有可能避免这种情况?
一点背景资料:
我在玩 urwid,一个用于 python 的TUI library。用户界面通过调用urwid.MainLoop.run() 启动,并通过raise urwid.ExitMainLoop() 结束。到目前为止,这工作正常,但是当引发另一个异常时会发生什么?例如。当我捕捉到KeyboardInterrupt(urwid MainLoop 没有)时,我会进行一些清理并希望通过引发适当的异常来结束用户界面。但这会导致屏幕上满是堆栈跟踪。
一些小研究表明 python3 可以记住链式异常,并且可以通过“原因”显式引发异常:raise B() from A()。我学习了一些方法来更改或附加有关引发异常的数据,但我发现无法“禁用”此功能。我想避免打印堆栈跟踪和像The above exception was the direct cause of... 这样的行,而只是在except: 块内引发接口结束异常,就像我在一个块之外一样。
这是可能的还是我做错了什么?
编辑: 这是一个类似于我当前架构的示例,导致相同的问题:
#!/usr/bin/env python3
import time
class Exit_Main_Loop(Exception):
pass
# UI main loop
def main_loop():
try:
while True:
time.sleep(0.1)
except Exit_Main_Loop as e:
print('Exit_Main_Loop')
# do some UI-related clean up
# my main script
try:
main_loop()
except KeyboardInterrupt as e:
print('KeyboardInterrupt')
# do some clean up
raise Exit_Main_Loop() # signal the UI to terminate
不幸的是,我也无法将 main_loop 更改为 KeyboardInterrupt 之外的其他内容。有解决这个问题的模式吗?
【问题讨论】:
-
您是根本不需要堆栈跟踪,还是只需要最外面的异常的堆栈跟踪,还是只需要最里面的异常的堆栈跟踪?
-
如果您不想要 any 堆栈跟踪,只需将整个“主”代码包装在
try:/except Exception as e:中,然后根据需要处理异常(例如,print(repr(e)); sys.exit(1))。 -
我不希望有任何指示发生异常(对于用户)- 没有堆栈跟踪或其他文本输出(当然,除了我自己打印的内容)。我的意思是,我发现了异常并做了我必须做的事情——不再需要堆栈跟踪(如果我想阅读它,我会自己打印它)。类似地,urwid.MainLoop 也以静默方式捕获 Exit 异常。我看不出为什么仅仅因为连续有两个异常(都被正确捕获)就应该导致类似于未捕获异常的输出。
-
我还是不明白你的问题。您能否给我们一个 SSCCE 来证明您的问题(最好是不使用
urwid或任何其他事件循环的)? -
我添加了一个小例子,类似于我的“设计”和问题。
标签: python exception python-3.x urwid