2011-09-19 13 views
5

Czy jest jakiś sposób w Pythonie do kontynuowania iteracji po wyjściu wyjątku przez iterator/generator? Podobnie jak w poniższym kodzie, istnieje sposób na pominięcie ZeroDivisionError i kontynuowanie zapętlenia się przez gener() bez funkcji modyfikującej run()?Kontynuuj po podniesieniu wyjątku w iteratorze/generatorze w pythonie

def gener(): 
    a = [1,2,3,4,0, 5, 6,7, 8, 0, 9] 
    for i in a: 
     yield 2/i 

def run(): 
    for i in gener(): 
     print i 

#---- run script ----# 

try: 
    run() 
except ZeroDivisionError: 
    print 'what magick should i put here?' 

Odpowiedz

8

Logicznym miejscem dla try/except byłoby miejsce, gdzie odbywa się obliczanie wykraczająca:

def gener(): 
    a = [1,2,3,4,0, 5, 6,7, 8, 0, 9] 
    for i in a: 
     try: 
      yield 2/i 
     except ZeroDivisionError: 
      pass 
+1

W tym prostym przypadku prawdopodobnie tak. Ale co jeśli chcemy funkcji, w której iteracja jest domyślnie zatrzymana, ale możemy kontynuować z następnym elementem wychwytującym wyjątek? Powinniśmy mieć zewnętrzny sygnał, że coś jest nie tak. – sergzach

+0

@sergzach: Moglibyśmy zrobić coś w stylu 'yield None' zamiast' pass' i złap ten specjalny przypadek w wywołującego. –

2

Jednym z możliwych rozwiązań jest po prostu zawijania kod problemu w bloku try ... except:

def gener(): 
    a = [1,2,3,4,0, 5, 6,7, 8, 0, 9] 
    for i in a: 
     try: 
      div_result = 2/i 
     except ZeroDivisionError: 
      div_result = None 

     yield div_result 
0

Nie jestem pewien, ale może to ci pasuje lepiej, jeśli chcesz nadal rozumieć, gdzie pojawiły się błędy:

def gener(): 
    a = [1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9] 
    errors = [] 
    for idx, i in enumerate(a): 
     try: 
      yield 2/i 
     except ZeroDivisionError: 
      errors.append('ZeroDivisionError occured at idx = {}'.format(idx)) 
    raise RuntimeWarning('\n'.join(errors)) 
Powiązane problemy