Python:我不允许引发异常。还有其他优雅的蟒蛇方式吗?

时间:2010-10-06 03:34:09

标签: python exception raise

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

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中有比这更优雅的方法吗?

3 个答案:

答案 0 :(得分:3)

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

谁提出这个一揽子政策肯定会考虑另一种语言(也许是C ++?),其中抛出异常是一种更昂贵的操作(如果你的代码在一台20岁的计算机上执行,将会降低性能)。

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

答案 1 :(得分:1)

返回None相当普遍,并且在概念上运作良好。如果你期望得到一个返回值,并且你没有得到任何回报值,那就表明出现了问题。

另一种可能的方法是,如果您希望返回列表(或字典等),则返回列表或dict。这可以很容易地使用if进行测试,因为一个空容器在Python中求值为False,如果你要迭代它,你可能甚至不需要检查它(取决于什么)如果函数失败,你想做什么。)

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

最后,我会努力改变这个荒谬的政策,因为异常是Python工作方式的一个重要部分,开销很低,任何使用你的功能的人都会期望。

答案 2 :(得分:1)

您必须使用返回代码。其他替代方案将涉及可变的全局状态(想想C的错误)或传入可变对象(例如列表),但是你几乎总是希望在Python中避免这两者。也许您可以尝试向他们解释如何exceptions let you write better post-conditions而不是将复杂性添加到返回值,但在其他方面是等效的。