什么是pythonic方式来冒泡错误条件

时间:2014-05-22 04:28:36

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

我一直在研究一个有点大的Python项目,它有几层功能。由于一些愚蠢的早期决定,我发现我必须修复很多crashers,因为较低级别的函数返回的类型我没有在高级函数中预期(通常为None)。

在我完成清理之前,我想知道什么是指示错误条件并在更高功能中处理它们的最pythonic方式?

我一直在做的大部分是如果一个函数无法完成并返回其预期结果,我将返回None。这有点粗略,因为你最终必须在所有调用它的函数中检查None。

def lowLevel():
    ## some error occurred
    return None

    ## processing was good, return normal result string
    return resultString

def highLevel():
    resultFromLow = lowLevel()
    if not resultFromLow:
        return None

    ## some processing error occurred
    return None

    ## processing was good, return normal result string
    return resultString

我想另一个解决方案可能是抛出异常。有了这个,您仍然可以在调用函数中获得大量代码来处理异常。

似乎没有超级优雅。其他人使用什么?在obj-c中,常见的模式是通过引用返回错误参数,然后调用者检查它。

3 个答案:

答案 0 :(得分:5)

这实际上取决于你想要做什么才能完成这个处理。如果这些是普通控制流程的真正例外,并且您需要清理,拯救,向人们发送电子邮件等,那么异常就是您想要抛出的内容。在这种情况下,处理代码只是必要的工作,并且基本上是不可避免的,尽管你可以重新抛出堆栈并在一个地方处理错误以保持它更整洁。

如果可以容忍这些错误,那么一个优雅的解决方案就是使用Null Object模式。您返回一个对象,该对象模仿通常会返回的真实对象的界面,但不会做任何事情。这允许故障下游的所有代码继续运行,而忽略了失败的事实。这种模式的主要缺点是它很难发现真正的错误,因为你的代码不会崩溃,但在运行结束时可能不会产生任何有用的东西。

Python中Null对象模式的一个常见示例是当您的低级别功能出现空白时返回空列表或字典。使用此返回值并迭代元素的任何后续函数都将以静默方式进行,而无需进行错误检查。当然,如果您要求列表由于某种原因至少有一个元素,那么这将无法工作,并且您又会重新处理异常情况。

答案 1 :(得分:3)

这不一定是 Pytonic ,但是经验告诉我要让例外"谎言他们撒谎的地方"。

也就是说;不要不必要地隐藏它们或重新引发不同的例外。

让被叫方失败而不是试图捕捉和隐藏各种错误情况,这有时是一种很好的做法。

显然这个话题是,并且可能有点主观;但是如果你不隐藏或引发不同的异常,那么调试你的代码要容易得多,而且你的函数被调用者或api更容易理解错误。

注意:此答案未完成 - 请参阅注释。本Q& A中提出的部分或全部答案应该以一种很好的方式结合起来,以清晰简洁的方式解决各种问题和解决方案。

答案 2 :(得分:3)

从好的方面来说,您已经发现使用返回值来指示错误情况的确切问题。

Exception是处理问题的pythonic方法。你必须回答的问题(我怀疑你已经做过)是:low_level函数可以返回一个有用的默认值吗?如果是这样的话,拿走它并随之运行;否则,引发异常(`ValueError',' TypeError'甚至自定义错误)。

然后,进一步调用堆栈,,你知道如何处理问题,捕获异常并处理它。您不必立即捕获例外情况 - 如果high_level调用mid-level来电low_level,那么try/except中没有任何mid_level就可以了1}}让high_level处理它。可能你所能做的就是在你的程序顶部有一个try/except来捕获并记录所有未捕获和未处理的错误,这可能没问题。