【问题标题】:Catch exception by __cause__通过 __cause__ 捕获异常
【发布时间】:2019-08-22 13:10:10
【问题描述】:

Python 3 允许从其他异常中引发异常,例如:

try:
  raise CustomException()
except CustomException as e:
  try:
    raise TypeError() from e
  except TypeError as e:
    print(type(e.__cause__))

CustomException 实例存储在异常对象的__cause__ 属性中。 上面的代码应该打印CustomException

有没有办法捕捉原始异常而不是新引发的异常?

try:
  raise CustomException()
except CustomException as e:
  try:
    raise TypeError() from e
  except CustomException as e:
    print(type(e)) # should reach here

覆盖 __subclasscheck__ 不起作用,因为我无权访问该实例,并且无法指定 CustomException is a subclass of all classes or of the cause class

有没有办法让 Python 认为我们捕获的异常是 __cause__ 类型的?

【问题讨论】:

标签: python python-3.x exception


【解决方案1】:

如果您可以控制引发的异常,您也许可以将其设为引发异常的子类:

try:
   raise TypeError()
except TypeError as e:
   try:
      class CustomException(TypeError.__class__):
         pass
      raise CustomException() from e
   except TypeError as e:
      print(type(e))  # Reaches here

也就是说,catch-and-reraise 机制旨在隐藏原始异常是什么,以便以后的代码不依赖于实现细节。

【讨论】:

    【解决方案2】:

    简单的解决方案:捕获所有异常并过滤所需:

    try:
        raise ZeroDivisionError()
    except ZeroDivisionError as e:
        try:
            raise TypeError() from e
        except Exception as ex:
            if type(ex.__cause__) is ZeroDivisionError:
                print('ZeroDivisionError')
            else:
                raise  # re-raise exception if it has different __cause__
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 2016-01-28
      • 2019-08-11
      相关资源
      最近更新 更多