【问题标题】:Raising exception with two arguments使用两个参数引发异常
【发布时间】:2017-02-21 00:48:55
【问题描述】:

再次问候 StackOverflow 社区,

我正在阅读一位同事写的图书馆,发现了一些我不太了解他们想要做什么的东西。但也许这是我在 Python 语法方面缺少的东西。

class SampleClass:
    def some_function(self) -> None:
       try:
           self.do_something()
       except CustomException as e:
           raise DifferentExceptionClass("Could not do something", e)
           # The previous line is the cause of bewilderment.

    def do_something(self) -> None:
        raise CustomException("Tried to do something and failed.")

我读过 raise 可以接受参数,但这似乎引发了以元组作为值的 DifferentExceptionClass 异常。我的同事在这里所做的与 raise DifferentExeptionClass("Could not do something. {}".format(e)) 这样的事情有什么区别?以他的方式提出异常有什么好处吗?

对 some_function() 的函数调用的输出是:

test = SampleClass()
test.some_function()
Traceback (most recent call last):
  File "<input>", line 4, in some_function
  File "<input>", line 10, in do_something
CustomException: Tried to do something and failed.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 6, in some_function
DifferentExceptionClass: ('Could not do something', CustomException('Tried to do something and failed.',))

编辑:无法联系到该同事发表评论。他们也很久以前写了这个库,可能不记得他们写这个时的“心情”。我认为如果其他人看到类似的实现,它也会对 SO 进行很好的讨论。

【问题讨论】:

  • 不,您只需调用构造函数,它需要两个参数...

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


【解决方案1】:

这样做肯定有好处。您链接异常并将该链作为信息提供给用户,而不是提供最近创建的异常。

当然,您的同事可以使用 Python 提供的语法以更好的方式完成此操作。 raise exc from raised_exc 语法用于在引发另一个异常后引发异常:

except CustomException as e:
    raise DifferentExceptionClass("Could not do something") from e

如果您需要查看它,则将e(引发的异常,此处为CustomException)存储为最新异常(此处为DifferentExceptionClass)的__cause__ 属性。

如果在except 处理程序中使用raise(就像在您的代码sn-p 中发生的那样),之前的异常(e已经隐式存储__context__ 属性。因此,也将其作为参数传递,除了将异常存储在 args 元组中之外,不会做任何其他事情。

【讨论】:

    【解决方案2】:

    我读过 raise 可以接受参数,但这似乎引发了以元组为值的 DifferentExceptionClass 异常。

    Exceptions 实际上也是类。事实上,你会在某个地方找到类似的东西:

    class DifferentExceptionClass(Exception):
    
        def __init__(self,message,innerException):
            # ...
            pass
    

    所以你调用构造函数。如何处理参数取决于例外情况。消息有可能被内部异常格式化,但也有可能它做了一些完全不同的事情。

    优点是例如innerException(或其他参数)可以相应地存储、检查和处理。如果您格式化异常,真正的异常数据会丢失:您只有它的文本表示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-23
      • 2012-02-20
      • 2023-03-03
      • 2014-06-11
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      相关资源
      最近更新 更多