引发 python 异常,然后继续

Raise a python Exception and then continue

我有一个代码片段,我已将其包装在我自己的装饰器中。我的装饰器简单地“捕获”所有异常,然后打印它们,然后重新引发它们。然而,当我有多个函数相互调用时,这给我带来了一个问题,因为它们都被打印出来了。 示例:

@error_wrapper
def myFunction(x, y):
    return int_div(x, y)
    
@error_wrapper
def int_div(x, y):
    return x//y

从上面的代码可以看出,只要y为0,函数就会因为DivisionByZero而出错。现在,由于这两个函数都包含在我的 error_wrapper 中,它基本上是一个装饰器:

try:
    return func(*args, **kwargs)
except Exception as e:
    print(e)
    raise

这里的问题是 raise 发生在 myFunctionint_div 中,这是包装两个函数的副作用。所以我满意的解决方案不是再次 raise 错误,我只是做一个 return 没有 return 值,但这会让我失去回溯,这是我调试代码所必需的。我看过 traceback 模块,我也试过了,但现在我面临的问题是 return 是 returning None,这不是预期的行为。关于如何解决这个问题的任何见解?

您可以简单地在错误本身上设置一个标志,然后检查该标志。我正在使用一些冗长的东西来希望避免任何名称冲突。

def error_wrapper(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            if not hasattr(e, "_error_wrapper_printed"):
                e._error_wrapper_printed = True
                print(e)
            raise
    return wrapper


@error_wrapper
def myFunction(x, y):
    return int_div(x, y)
    
@error_wrapper
def int_div(x, y):
    return x//y

print(myFunction(1, 0))

以上产生的行为(我相信)符合您的需要。

integer division or modulo by zero
Traceback (most recent call last):
  File "c:\Users\david\Desktop\tmp.py", line 21, in <module>
    print(myFunction(1, 0))
  File "c:\Users\david\Desktop\tmp.py", line 4, in wrapper
    return func(*args, **kwargs)
  File "c:\Users\david\Desktop\tmp.py", line 15, in myFunction
    return int_div(x, y)
  File "c:\Users\david\Desktop\tmp.py", line 4, in wrapper
    return func(*args, **kwargs)
  File "c:\Users\david\Desktop\tmp.py", line 19, in int_div
    return x//y
ZeroDivisionError: integer division or modulo by zero