在发电机中分析例外情况

时间:2013-02-28 13:16:57

标签: python exception generator

我经常有一个生成器,它迭代某些集合,处理元素并产生结果。元素的处理可能会引发异常。我想在发生器的调用者中处理这样的发生器中发生这种异常,而不终止发生器。毕竟,只是处理失败,而不是迭代,因此生成器可以继续下一个迭代元素。显示情况的示例:

def generator():
  for element in collection:
    yield process(element)  # might raise Exception

def caller():
  for product in generator():
    doSomethingWith(product)

我想处理process()caller()引发的异常。不幸的是,process()中的异常将在generator()中发生,从而终止生成器(如果我们在这里不做更复杂的事情)。所以天真的方法会失败:

def generator():
  for element in collection:
    yield process(element)  # might raise Exception

def caller():
  for product in generator():
    try:   # wrong place for try, as the loop will already fail
      doSomethingWith(product)
    except Exception as problem:
      handleProblem(problem)

我目前的工作但有缺陷的方法是将异常分发为产生的价值:

def generator():
  for element in collection:
    try:
      yield process(element)  # might raise Exception
    except Exception as problem:
      yield problem

def caller():
  for yielded in generator():
    if isinstance(yielded, Exception):
      problem = yielded
      handleProblem(problem)
    else:
      product = yielded
      doSomethingWith(product)

这有效,但有一些缺点,如

  • 这取决于可以区分产品和异常的事实(不会对通常产生异常的生成器起作用)。当然,我们可以使用包装来解决这个问题。
  • 在收到生成的值(if isinstance(...))后立即需要这种丑陋的检查模式。
  • 它不使用正常的Python异常处理,因此重新引发异常等问题可能会造成问题(没有彻底检查)。

你有更好的方法吗?我更喜欢在try中使用一些except / caller()模式来处理异常,而不是使用if,因为它提供了更多的灵活性,例如只捕获特定的异常(和别人没有。)

0 个答案:

没有答案