2012-12-21 17 views
5
def funcA(i): 
    if i%3==0: 
     print "Oh! No!", 
     print i 
     break 

for i in range(100): 
    funcA(i) 
    print "Pass", 
    print i 

Wiem, że powyższy skrypt nie zadziała. Jak mogę napisać, jeśli potrzebuję funkcji z przerwą lub kontynuować w pętli?Przerwij i kontynuuj w funkcji

Odpowiedz

11

Funkcja nie może powodować przerwania ani kontynuować kodu, z którego jest wywoływana. Przerwa/kontynuacja musi pojawić się dosłownie w pętli. Dostępne są następujące opcje:

  1. zwrócić wartość z funcA i użyć go do podjęcia decyzji, czy należy przerwać
  2. wyjątek w funcA i złapać go w kodzie wywołującym (lub gdzieś wyżej w łańcuchu połączeń)
  3. napisać generator, który hermetyzuje logiki przerwę i iteracyjne nad tym, że zamiast nad range

Poprzez # 3 mam na myśli coś takiego:

def gen(base): 
    for item in base: 
     if item%3 == 0: 
      break 
     yield i 

for i in gen(range(1, 100)): 
    print "Pass," i 

Umożliwia to zerwanie warunku przez zgrupowanie go w generator na podstawie iteratora "podstawowego" (w tym przypadku zakresu). Następnie wykonujesz iterację na tym generatorze zamiast na samym zakresie i uzyskujesz zachowanie łamania.

+1

generator, który hermetyzuje logikę przerwań? – ThunderEX

+0

@ThunderEX - coś takiego jak 'itertools.takewhile' prawdopodobnie – eumiro

+0

@ThunderEX: Tak, podobne do takewhile. Zobacz moją zredagowaną odpowiedź. – BrenBarn

2
def funcA(i): 
    if i%3==0: 
     print "Oh! No!", 
     print i 
     return True 
    else: 
     return False 

for i in range(100): 
    if funcA(i): 
     break 
    print "Pass", 
    print i 
+0

mógłbyś dodać wyjaśnienie, w jaki ten kod odpowiada na pytanie? –

1

Przerwa nie będzie się rozprzestrzeniać między funkcjami, musisz umieścić ją bezpośrednio w pętli gdzieś.

2

Opracowanie BrenBarns odpowiedź: breakna szczęście nie będzie propagować. break jest przerwanie bieżącej pętli, kropka. Jeśli chcesz propagować zdarzenie, to powinieneś uzyskać wyjątek od raise. Chociaż podniesienie wyjątku w celu przerwania pętli to naprawdę paskudny sposób na przerwanie pętli i dobry sposób na złamanie kodu.

KISS! Najprostszym byłoby sprawdzić stan bezpośrednio w pętli

def my_condition(x): 
    return x == 4 

for i in xrange(100): 
    if my_condition(i): break 
    print i 

Jeśli z jakiegoś powodu chcesz propagować wyjątek, a następnie go używać jak to

# exception example 
for i in xrange(100): 
    if i == 4: raise Exception("Die!") 
    print i 

Jak wspomniano, jest naprawdę brzydki projekt. Wyobraź sobie zapomnieć złapać ten wyjątek, lub zmienić jego typ z Exception do MyBreakException i zapomnij zmienić go gdzieś w try/except wyższej części kodu ...

Przykładowy generator ma swoje zalety, to sprawia, że ​​Twój kod bardziej functional style (co presonally adorować)

# generator example 
def conditional_generator(n, condition): 
    for i in xrange(n): 
    if condition(i): 
     break 
    else: 
     yield i 


for i in conditional_generator(100, my_condition): 
    print i 

... który jest podobny do takewhile, wspomniane przez eumiro