2016-10-11 55 views
3

我使用函数f创建生成器,但有时它可能会引发错误。我想两件事情发生在主代码蟒蛇尝试,除了产量组合

  1. for环路主块捕获错误
  2. 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' 
+3

如果在生成器内部引发异常,我看不到任何方法来恢复该生成器的执行,除非你在生成器内部捕获异常。 – vaultah

+1

目前还不清楚,如果你想继续迭代器内的'for'或'main'中的'for' .... –

+0

我想让main块中的'for'继续。原文编辑。 – nos

回答

4

你将不得不捕获异常您的发电机,如果你想它的循环继续运行。这是一个工作示例:

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 
2

由于OP澄清,他要继续主要用于循环在错误的情况下,内发生器,显示发生错误的索引。

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 

通常这是不太可能的发电机正在产生异常类,因此,如果结果是一个例外,处理它,它是安全的检查。

1

我怀疑,通常情况下,您希望能够捕获导致错误条件的值。不停止发电机内部的环路。这是另一种方法,它在生成器的结果中包含一个布尔值(作为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