1

我的工作场所规定了不使用异常的规则(允许捕捉)。如果我有这样的代码

def f1()
 if bad_thing_happen():
   raise Exception('bad stuff')
 ...
 return something

我可以将其更改为

def f1()
  if bad_thing_happen():
    return [-1, None]
  ...
  return [0, something]

f1 调用者会是这样的

def f1_caller():
  code, result = f1(param1)
  if code < 0:
    return code
  actual_work1()
  # call f1 again
  code, result = f1(param2)
  if code < 0:
    return code
  actual_work2()
  ...

在 Python 中有比这更优雅的方法吗?

4

3 回答 3

3

python 中的异常是不可避免的,通常是解决问题的直接方法。此外,异常带有大量信息,可以帮助快速定位(通过堆栈跟踪)和识别问题(通过异常类或消息)。

提出这一全面政策的人肯定是在考虑另一种语言(可能是 C++?),其中抛出异常是一项更昂贵的操作(如果您的代码在 20 年的旧计算机上执行,则会降低性能)。

回答您的问题:另一种方法是返回错误代码。这意味着您将函数结果与错误处理混合在一起,这会引发(哈!)它自己的问题。但是,返回None通常是指示功能失败的完全合理的方式。

于 2010-10-06T03:42:42.550 回答
1

返回None是相当普遍的,并且在概念上运作良好。如果您期望返回值,但没有得到,这很好地表明出现了问题。

如果您希望返回一个列表(或字典等),另一种可能的方法是返回一个列表或字典。这可以很容易地使用 进行测试if,因为空容器False在 Python中的计算结果为

当然,这些方法并不能告诉您函数失败的原因。所以你可以返回一个异常实例,例如return ValueError("invalid index"). 然后,您可以使用并打印它们来测试特定的异常(或一般的异常)isinstance()以获得体面的错误消息。(或者您可以提供一个辅助函数来测试返回码以查看它是否派生自Exception。)您仍然可以创建自己的Exception子类;您只会退回它们而不是提高它们。

最后,我将努力改变这个荒谬的政策,因为异常是 Python 工作方式的重要组成部分,开销低,并且任何使用你的函数的人都会期望。

于 2010-10-06T03:50:34.210 回答
1

您必须使用返回码。其他替代方案将涉及可变全局状态(想想 C 的 errno)或传入可变对象(例如列表),但您几乎总是希望在 Python 中避免这两种情况。也许您可以尝试向他们解释异常如何让您编写更好的后置条件,而不是为返回值添加复杂性,但在其他方面是等效的。

于 2010-10-06T03:54:05.463 回答