通过contextlib有一个带有装饰器生成的上下文管理器的简单代码。当我按下按钮异常时,上下文管理器不处理。为什么?
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()
为什么异常仍然会提高?
UPD我使用Python 2.7
答案 0 :(得分:3)
Tkinter主进程循环不会被异常关闭,也不会进一步传播它们。因此,异常永远不会到达with
语句(因为tkinter本身捕获并报告异常然后停止执行)。
您需要创建一个装饰器来捕获这些异常并记录它们或执行您想要做的任何逻辑。
示例 -
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()
使用上面的代码,当我点击Press
按钮时,它会为我记录Exception catched1
并退出。
此外,except:
你应该给你想要捕获的异常(或至少except Exception:
)是不好的。