【问题标题】:What is preferable way to handle exceptions?处理异常的更好方法是什么?
【发布时间】:2016-06-12 04:38:22
【问题描述】:

如果我在编写一些代码时不确定某事,我会尝试再次阅读The Zen of Python。这一次,那些台词让我犹豫了。

Errors should never pass silently.
Unless explicitly silenced.

在当前代码中,我有一些看起来像这样的函数:

def add_v_1(a, b):
    return a + b 

所有对他们的要求如下:

c = add_v_1(7, [])

此类代码的异常会冒泡并在上层捕获。

但应该是这样吗?

add_v_1 可以引发TypeError 异常,我想从中恢复。 所以,可能的函数调用是:

try:
    c = add_v_1(7, [])
except TypeError:
    print "Incorrect types!"

但是对于每次调用,我都应该进行异常处理。看起来很重。

所以,我可以这样做:

def add_v_2(a, b):
    try:
        return a + b
    except TypeError:
        print "Incorrect types!"

一个电话会是:

c = add_v_2(7, [])

看起来更干净。

似乎所有这些方法都遵循The Zen of Python,但其中哪一种是更好的选择?

【问题讨论】:

  • 我会说这取决于你的情况,如果你在函数内部处理异常,你仍然必须在外部处理它,因为它会返回 None。
  • @Haketo 您将如何处理当前示例?

标签: python exception zen-of-python


【解决方案1】:

当你能够从中恢复时,你应该处理它。如果您尝试添加两个类型不兼容的值,则无法从中恢复(没有进一步的上下文)。

假设您编写了一个 IntegerWrapper 类,并且您的函数“add_v_2”通常应该尝试连接两个值。

def add_v_2(a, b):
    try:
        return a + b
    except TypeError as e:
        if isinstance(a, IntegerWrapper):
            return str(a) + b
        else:
            print("I dont know how to handle this type: " + type(a).__name__)
            # reraise the error so the caller can handle it
            raise

这将尝试从“错误类型”的a 中恢复,但前提是您知道如何从中恢复。如果它不知道(a 是另一种类型),它会重新引发异常,以便知道如何处理的人看到错误。

(当然,该实现包含错误,它并不意味着是一个“好的实现”)

【讨论】:

    【解决方案2】:

    参考您的示例,您是否应该在函数内捕获异常是有争议的。这样做会从函数返回None,然后调用代码检查函数的返回值,并将None 视为错误。它有效地用错误检查代替了异常处理。前者通常更 Pythonic。

    您应该询问捕获错误是否有意义,例如尝试添加 2 种完全不同的数据类型。在这种情况下这样做似乎是一个编程错误,而不是您在正常执行期间所期望的那种事情。

    你能做些什么来处理这样的错误?在函数的预期输出域内似乎没有任何有用的值可以返回......除了None 表示无法产生结果。但是调用代码仍然必须执行某种错误检查......所以它还不如只处理一个异常 - 至少它只需要处理一次。

    但是这个例子是人为的,很难给出笼统的建议。在这种特殊情况下,出于上述原因,我会允许异常传播到调用代码并在那里处理它。

    【讨论】:

      【解决方案3】:

      输入:

      def add_v_2(a, b):
          try:
              return a + b
          except Exception as e:
              print str(e)
      c = add_v_2(7, [])
      print (c)
      

      输出:

      unsupported operand type(s) for +: 'int' and 'list'
      None
      

      【讨论】:

      • @viakondratiuk - 在你的代码中,第二个是最好的,如果有任何情况,你会再次做同样的事情,而无需再次使用 try catch
      • 我不建议抓Exception,这太一般了。您应该捕获您期望并且可以处理的异常,在这种情况下您可以捕获TypeError
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-25
      相关资源
      最近更新 更多