简体   繁体   English

为什么Python中的装饰风格的上下文管理器无法在Tkinter窗口中捕获异常?

[英]Why decorator-style context manager in Python doesn't catch exception within Tkinter window?

there is a simple code with decorator-generated context manager via contextlib. 装饰器生成的上下文管理器通过contextlib提供了一个简单的代码。 When I press button exception raised and DOES NOT handled by context manager. 当我按下按钮时引发异常,并且上下文管理器不处理。 Why is it? 为什么?

from Tkinter import Tk, Button
from contextlib import contextmanager


def close_window(): 
    window.destroy()
    raise Exception


@contextmanager
def safe():
    try:
        yield
    except:
        print 'Exception catched'

with safe():
    window = Tk()
    button = Button(window, text='Press me', command=close_window)
    button.pack()
    window.mainloop()

Why does exception still raise? 为什么异常还会引发?

UPD I use Python 2.7 我使用Python 2.7的UPD

The Tkinter main process loop is not brought down by exceptions and does not propagate them further. Tkinter主进程循环不会因异常而中断,并且不会进一步传播它们。 Hence, the exception never reaches till the with statement (since tkinter itself catches and reports the exception and then stops execution). 因此,直到with语句(直到tkinter本身捕获并报告该异常然后停止执行),该异常才会到达。

You will need to create a decorator to catch those exception and log them or do whatever logic you want to do. 您将需要创建一个装饰器来捕获那些异常并记录它们或执行您想执行的任何逻辑。

Example - 范例-

from Tkinter import Tk, Button
from contextlib import contextmanager

class exceptioncatcher: # <---the decorator
    def __init__(self, function):
        self.function = function
    def __call__(self, *args, **kwargs):
        try:
            return self.function(*args, **kwargs)
        except Exception:
            print 'Exception catched1'


@exceptioncatcher
def close_window(): 
    window.destroy()
    raise Exception


@contextmanager
def safe():
    try:
        yield
    except Exception:
        print 'Exception catched'

with safe():
    window = Tk()
    button = Button(window, text='Press me', command=close_window)
    button.pack()
    window.mainloop()

With the above code, when I click on the Press button, it logs Exception catched1 for me and exits. 使用上面的代码,当我单击“ Press按钮时,它将为我记录Exception catched1并退出。

Also, It is not good to do except: you should give the exception you want to catch (or atleast except Exception: ). 另外, except:操作except: ,这也不是一件好事except:您应提供要捕获的异常(或至少提供except Exception: )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM