我的理解是:通常,当发生错误时,它会通过所有调用函数抛出,然后显示在控制台中。现在有一些软件包可以自己进行错误处理,尤其是与GUI相关的软件包通常根本不显示错误,只是继续执行。
我们怎样才能覆盖这种行为呢?当我编写GUI函数时,我希望看到错误!我找到this post,其中解释了如何为Tkinter的情况做这件事。如何在Matplotlib中完成?
示例代码:
import matplotlib.pyplot as plt
def onclick(event):
print(event.x, event.y)
raise ValueError('SomeError') # this error is thrown but isn't displayed
fig = plt.figure(5)
fig.clf()
try: # if figure was open before, try to disconnect the button
fig.canvas.mpl_disconnect(cid_button)
except:
pass
cid_button = fig.canvas.mpl_connect('button_press_event', onclick)
答案 0 :(得分:1)
实际上,当python解释器遇到一个永远不会被捕获的异常时,它会在激发之前将所谓的回溯打印到stdout。但是,GUI包通常会捕获并吞下所有异常,以防止python解释器激动。您希望在某处显示该跟踪,但在GUI应用程序的情况下,您将必须决定在何处显示该跟踪。标准库有一个模块,可以帮助您处理这样的回溯,恰当地命名为traceback
。然后,您必须在GUI工具包执行之前捕获异常。我不知道插入回调错误处理程序的一般方法,但您可以手动为每个回调添加错误处理。执行此操作的最佳方法是编写一个函数装饰器,然后将其应用于回调。
import traceback, functools
def print_errors_to_stdout(fun):
@functools.wraps(fun)
def wrapper(*args,**kw):
try:
return fun(*args,**kw)
except Exception:
traceback.print_exc()
raise
return wrapper
@print_errors_to_stdout
def onclick(event):
print(event.x, event.y)
raise ValueError('SomeError')
装饰器print_errors_to_stdout
接受一个函数并返回一个新函数,该函数将原始函数嵌入try ... except
块中,并且在异常的情况下,在{{3}的帮助下将回溯打印到stdout }。 (包装器本身用traceback.print_exc()
修饰,以便生成的包装函数保留原始函数的文档字符串。如果你想在其他地方显示追溯functools.wraps
会给你一个字符串,然后你可以显示/存储somwhere。装饰者也重新引用异常,这样GUI工具包仍然有机会采取它自己的行为,通常只是吞下异常。