2012-12-21 13 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 

So che lo script sopra non funzionerà. Quindi, come posso scrivere se ho bisogno di inserire una funzione con pausa o continuare in un ciclo?interrompe e continua in funzione

risposta

11

Una funzione non può causare un'interruzione o continuare nel codice da cui è stata chiamata. La pausa/continua deve apparire letteralmente all'interno del ciclo. Le opzioni disponibili sono:

  1. restituire un valore da funcA e lo usano per decidere se rompere
  2. sollevare un'eccezione in funcA e prenderlo nel codice chiamante (o da qualche parte più in alto nella catena di chiamate)
  3. scrivere un generatore che incapsula la logica pausa e iterare che invece il range

in 3. intendo qualcosa di simile:

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

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

Ciò consente di interrompere la condizione raggruppandoli in un generatore basato sull'iterazione "base" (in questo caso un intervallo). Quindi si itera su questo generatore anziché sull'intervallo stesso e si ottiene il comportamento di interruzione.

+1

un generatore che incapsula la logica di interruzione? – ThunderEX

+0

@ThunderEX - qualcosa come 'itertools.takewhile' probabilmente – eumiro

+0

@ThunderEX: Sì, simile a takewhile. Vedi la mia risposta modificata. – 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

Potrebbe aggiungere una spiegazione di come questo codice risponde alla domanda? –

1

L'interruzione non si propagherà tra le funzioni, è necessario inserirlo direttamente nel ciclo da qualche parte.

2

Elaborare BrenBarns risposta: breakfortunatamente non si propagherà. break interromperà il ciclo corrente, punto. Se vuoi propagare un evento, allora devi raise un'eccezione. Anche se sollevare l'eccezione per interrompere il ciclo è un modo davvero brutto per rompere i loop e un bel modo per violare il codice.

KISS! Il più semplice sarebbe quello di controllare la condizione direttamente nel ciclo

def my_condition(x): 
    return x == 4 

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

Se, per qualche ragione, si desidera propagare un'eccezione, quindi si utilizza in questo modo

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

Come accennato, è a davvero brutto design. Immaginate si dimentica di prendere questa eccezione, o si cambia il tipo da Exception a MyBreakException e dimentica di cambiare da qualche parte in alto try/except parte del codice ...

L'esempio generatore ha i suoi meriti, rende il codice più functional style (che io adoro presonally)

# 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 

... che è simile a takewhile, citato da eumiro

Problemi correlati