python尝试除了yield组合

时间:2016-10-11 17:03:49

标签: python try-catch yield except

我使用函数f来创建生成器,但有时它会引发错误。我希望主代码发生两件事

  1. 在捕获错误
  2. 后,主块中的for循环继续
  3. except中,打印出生成错误的索引(实际上索引3可能不会出错)
  4. 我提出的代码在引发错误后停止。我该如何实现上述两个功能?非常感谢。

    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'
    

3 个答案:

答案 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