【问题标题】:Gracefully handle suppressed (unhandled) exceptions in PyQt4优雅地处理 PyQt4 中的抑制(未处理)异常
【发布时间】:2017-03-04 06:48:26
【问题描述】:

问题:

我正在尝试找出处理通常被 PyQt 抑制的未处理异常的最佳方法。

我现在的解决方案是用下面的装饰器装饰适当的方法

def handleExceptions(func):
    """
    Decorator: create and show message box for every unhandled exception that
    reaches the decorator
    """
    @functools.wraps(func)
    def decorator(self):
        try:
            func(self)
        except Exception as error:

            # ...

            if errBox.exec_() == QMessageBox.Ok:
                try:
                    self.closeApp()
                except AttributeError:
                    exit()

    return decorator

但是,此解决方案仅在没有任何修饰方法需要的参数多于 self 时才有效。我尝试像这样扩展装饰器

...
def decorator(self, *args)
    try:
        func(self, *args)
...

这允许调用带有一个或多个参数的函数(包括self)。不幸的是,这段代码破坏了对除 self 之外不需要参数的方法的访问,这些方法因消息 TypeError: method() takes 1 positional argument but 2 were given 而失败。

使用调试器后,我发现*args 中的第二个参数似乎是一个布尔值 (False)。

问题:

  1. 为什么要传递这个附加参数?
  2. 如何修改装饰器以允许使用不同参数长度的函数?
  3. 这甚至是处理异常的好方法吗?如果有人能告诉我在 PyQt 中处理未处理异常的常用方法,我将不胜感激。

我查找了其他解决方案,如 this one(我不完全理解)并尝试实施它们但没有成功(它要么抛出像我这样的异常,要么完全破坏修饰的方法)。

提前致谢!

【问题讨论】:

  • 装饰器看起来过于复杂且难以维护。您链接到的问题中的other answer 建议使用excepthook。我不知道为什么有人会考虑使用其他任何东西,因为它实现起来非常简单。

标签: python-3.x exception-handling pyqt4 decorator


【解决方案1】:

虽然我同意excepthook 可能是要走的路的评论,但我曾经做过类似的事情:

def handle_exception_decorator(exceptions_to_catch = (ValueError, IndexError, TypeError), return_on_fail=False):
    def wrap(fn):
        @functools.wraps(fn)
        def f(*args, **kwargs):
            try:
                return fn(*args, **kwargs)
            except tuple(exceptions_to_catch) as e:
                # handle the exception here:
                return return_on_fail
        return f
    return wrap

用以下方式装饰你的方法:

@handle_exception_decorator

@handle_exception_decorator(exceptions_to_catch=(AnExceptionType,))

@handle_exception_decorator(exceptions_to_catch=(Exception,), return_on_fail=7)    

等等……

编辑:哦,实际上我认为您的问题是因为您正在装饰的方法是连接到信号的插槽,而您的插槽忽略了信号发出的参数之一。解决这个问题的唯一方法是更新修饰函数以接受一个可选的关键字参数,该参数接受信号发出的参数。您当然不必在您的方法中使用它,您只需要方法签名来匹配信号将发出的内容(Qt 通常会优雅地处理这个问题,但是像这样的装饰器会搞砸!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-10
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 2017-02-18
    • 2015-12-14
    相关资源
    最近更新 更多