重试cod时的异常处理很好

2024-04-20 00:44:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些测试用例。测试用例依赖于需要时间计算的数据。为了加快测试速度,我缓存了数据,这样就不必重新计算了。在

我现在有了foo(),它查看缓存的数据。我不能提前告诉它会看到什么,因为这在很大程度上取决于测试用例。在

如果一个测试用例失败是因为它没有找到正确的缓存数据,我不希望它失败-我希望它计算数据,然后再试一次。我也不知道它会抛出什么异常导致丢失数据。在

我现在的代码如下:

if cacheExists:
    loadCache()
    dataComputed = False
else:
    calculateData()
    dataComputed = True

try:
    foo()
except:
    if not dataComputed:
        calculateData() 
        dataComputed = True
        try:
            foo()
        except:
            #error handling code
    else:
        #the same error handling code

重新构造代码的最佳方法是什么?在


Tags: 数据代码trueiffoo时间测试用例code
3条回答

有时没有好的方式来表达一个流,它只是复杂。但是这里有一种方法,只在一个地方调用foo(),并且只在一个地方进行错误处理:

if cacheExists:
    loadCache()
    dataComputed = False
else:
    calculateData()
    dataComputed = True

while True:
    try:
        foo()
        break
    except:
        if not dataComputed:
            calculateData()
            dataComputed = True
            continue 
        else:
            #the error handling code
            break

你可能不喜欢这个循环,YMMV。。。在

或者:

^{pr2}$
我不同意现有答案中的关键建议,基本上归结为处理Python中的异常,如C++或java,这不是Python中的首选样式,通常是一个好主意,“最好是请求原谅而不是许可”(尝试操作并处理例外,如果有的话)。而不是通过彻底的初步检查来模糊代码的主要流程和产生开销)。我确实同意Gabriel的观点,即裸的except几乎永远不是一个好主意(除非它所做的只是某种形式的日志记录,后面跟着一个raise让异常传播)。因此,假设您有一个元组,其中包含您期望的所有异常类型,并希望以相同的方式进行处理,例如:

expected_exceptions = KeyError, AttributeError, TypeError

并且总是使用except expected_exceptions:,而不是裸的except:。在

因此,如果不考虑这一点,一个稍微不那么重复的方法是:

^{pr2}$

另一种方法是使用辅助函数包装try/except逻辑:

def may_raise(expected_exceptions, somefunction, *a, **k):
  try:
    return False, somefunction(*a, **k)
  except expected_exceptions:
    return True, None

这样的助手通常在几种不同的情况下有用,所以在项目的“实用程序”模块中有这样的东西是很常见的。现在,对于您的案例(没有参数,没有结果),您可以使用:

failed, _ = may_raise(expected_exceptions, foo1)
if failed and condition:
  failed, _ = may_raise(expected_exceptions, foobetter)
if failed:
  handleError()

我认为它更线性化,因此更简单。这种通用方法的唯一问题是,may_raise这样的辅助函数不会强迫您以某种方式处理异常,因此您可能会忘记这样做(就像使用返回码而不是异常来指示错误一样,很容易错误地忽略这些返回值);因此,少用它。。。!-)在

使用一揽子例外通常不是一个好主意。你认为那里会有什么样的例外?是键错误,属性错误,类型错误。。。在

一旦确定了要查找的错误类型,就可以使用hasattr()in运算符之类的东西,或者在处理异常之前对您的条件进行测试。在

这样你就可以清理你的逻辑流,并省去你的异常处理那些真正被破坏的东西!在

相关问题 更多 >