我经常有一个生成器,它迭代某些集合,处理元素并产生结果。元素的处理可能会引发异常。我想在发生器的调用者中处理这样的发生器中发生这种异常,而不终止发生器。毕竟,只是处理失败,而不是迭代,因此生成器可以继续下一个迭代元素。显示情况的示例:
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(...)
)后立即需要这种丑陋的检查模式。你有更好的方法吗?我更喜欢在try
中使用一些except
/ caller()
模式来处理异常,而不是使用if
,因为它提供了更多的灵活性,例如只捕获特定的异常(和别人没有。)