2016-08-01 90 views
0

我的理解是:通常,当发生错误时,它通过所有调用函数抛出,然后显示在控制台中。现在有一些软件包可以自己处理错误,特别是与GUI相关的软件包通常不会显示错误,只是继续执行。如何在mpl_connect()回调函数中显示错误消息

我们如何重写这种行为?当我编写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) 

回答

1

事实上,在Python解释器遇到从未捕获的异常,它会打印一个所谓的回溯之前激动人心到标准输出。但是,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块中的原始功能,并在出现异常的情况下,打印回溯与traceback.print_exc()帮助到stdout新的功能。 (包装器本身装饰有functools.wraps,这样生成的包装函数,除其他外,保留原始函数的文档字符串)。如果您想在其他地方显示回溯,traceback.format_exc()会给你一个字符串,然后你可以显示/存储somwhere。装饰器也重新渲染异常,使得GUI工具包仍然有机会采取它自己的操作,通常只是吞噬异常。