优雅地处理PyQt4中的抑制(未处理)异常

时间:2016-10-21 21:04:40

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

问题:

我正在试图找出处理通常被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中的第二个参数似乎是一个bool(False)。

问题:

  1. 为什么要传递这个附加参数?
  2. 如何修改装饰器以允许使用不同参数长度的函数?
  3. 这是处理异常的好方法吗?如果有人能告诉我处理PyQt中未处理的异常的常用方法,我将不胜感激。
  4. 我查找了其他解决方案,例如this one(我并不完全理解),并试图实现它们但没有成功(它会抛出像我这样的异常或完全破坏装饰方法)。

    提前致谢!

1 个答案:

答案 0 :(得分:1)

虽然我同意以下评论,但也许是可行的方法,这里有类似我做过的事情:

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通常会优雅地处理这个,但装饰者就像这样搞乱了!)