2016-10-11 20 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