我使用函数f
来创建生成器,但有时它会引发错误。我希望主代码发生两件事
for
循环继续
except
中,打印出生成错误的索引(实际上索引3可能不会出错)我提出的代码在引发错误后停止。我该如何实现上述两个功能?非常感谢。
def f(n):
for i in xrange(n):
if i == 3:
raise ValueError('hit 3')
yield i
if __name__ == '__main__':
a = enumerate(f(10))
try:
for i, x in a:
print i, x
except ValueError:
print 'you have a problem with index x'
答案 0 :(得分:4)
如果希望其循环继续运行,则必须捕获 in 生成器。这是一个有效的例子:
def f(n):
for i in xrange(n):
try:
if i == 3:
raise ValueError('hit 3')
yield i
except ValueError:
print ("Error with key: {}".format(i))
像在你的例子中一样迭代它:
>>> for i in f(10):
... print (i)
...
0
1
2
Error with key: 3
4
5
6
7
8
9
答案 1 :(得分:2)
截至OP澄清,他希望在发生器内部出现错误的情况下继续外部 main for循环,显示错误发生在哪个索引。
brianpck的回答采用修改生成器的方法,以便打印错误。这样主循环就不知道在该索引处发生了错误,因此您在索引x-1处得到错误后的结果。有时你会关心这个假设"一个索引< - >一个结果"。
要解决这个问题,我们可以通过产生错误来手动管理错误,然后决定在生成器中做什么。
喜欢以下内容:
def f(n):
for i in xrange(n):
if i == 3:
yield ValueError('hit 3')
continue # or break, depends on problem logic
yield i
if __name__ == '__main__':
a = enumerate(f(10))
for i, x in a:
if isinstance(x, ValueError):
print "Error at index", i
continue
print i, x
通常情况下,生成器不太可能产生异常类,因此检查结果是否为异常并处理它是安全的。
答案 2 :(得分:2)
我怀疑,一般来说,您希望能够捕获导致错误条件的值。不停止发电机内的回路。这是另一种方法,包括生成器结果中的布尔值(作为2元组),指示计算是否可以成功完成。
def f(n):
for i in range(n):
accept=True
try:
result=1/(3-i)
except:
accept=False
yield accept, i
a=enumerate(f(10))
for k,(ok,i) in a:
print (ok,i)
在这种情况下,只有值3会导致失败。这是输出。
True 0
True 1
True 2
False 3
True 4
True 5
True 6
True 7
True 8
True 9