【问题标题】:Catching exception inside a decorator在装饰器中捕获异常
【发布时间】:2019-10-05 23:39:06
【问题描述】:

这个问题理论上可能不正确,但想知道是否有任何解决方法。

让我们考虑以下示例:

def my_function():
    try:
        print("before the exception occurs")
        raise ValueError
    except ValueError:
        print('exception found')

    print("after the exception occurs")


if __name__ == "__main__":
    my_function()

如果打印到标准输出,输出应该如下:

before the exception occurs
exception found
after the exception occurs

但是,如果您使用装饰器来捕获异常,如下所示:

from functools import wraps


def decorator(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    try:
        return func(*args, **kwargs)
    except ValueError:
        print('exception found')

  return wrapper


@decorator
def my_exception_function():
  print("before the exception occurs")

  raise ValueError

  print("after the exception occurs")


if __name__ == "__main__":
  my_exception_function()

异常发生后的其余函数将不会执行如下:

before the exception occurs
exception found

因此,我想知道是否有任何解决方法可用于获取第一个示例输出但使用装饰器捕获异常。

【问题讨论】:

  • 您希望在从外部捕获错误后能够返回到包装函数内部的稍后点?这不行,包装的函数调用已经完成。
  • 出现异常后,无法继续执行代码块的代码。即使你抓住它。
  • 想象一下你有像a = 1 / 0 \n print(a) 这样的行。即使你捕捉到 ZeroDivisionError,你怎么能在它之后打印一个呢?它会有什么价值?

标签: python exception decorator python-decorators


【解决方案1】:

让我们尝试在装饰器中内联my_exception_func。

from functools import wraps


def decorator(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    try:
        print("before the exception occurs")
        raise ValueError
        print("after the exception occurs")
    except ValueError:
        print('exception found')

  return wrapper

所以现在控制流应该更清晰了:

  • 打印'异常之前'
  • 引发异常
  • 转到except block
  • 返回

由于异常,永远无法达到“异常后”打印。

使用 try-except 块来捕获异常,但在异常点之后执行代码实际上并不能正常工作。您需要确切地在可能发生异常的位置进行隔离,并仅将该部分包装在 try-except 块中。

【讨论】:

    猜你喜欢
    • 2013-08-22
    • 2013-12-31
    • 2016-06-16
    • 2011-05-14
    • 2019-06-23
    • 2016-05-12
    • 2014-11-30
    • 1970-01-01
    • 2020-01-10
    相关资源
    最近更新 更多