Rompe il grande metodo in 2 metodi, prima contenente un ciclo "for" e il secondo un "break"

2

Un metodo è diventato troppo grande per il suo bene e ho bisogno di suddividerlo in due metodi separati.

def big_method(dct):

    # Initial code
    # ...
    for i in dct:
        # More code
        # ...
        for j in dct[i]:    
            # Inner code
            # ...
            # ...
            # and a break
            if j == 'something':
                break
            # Inner code ended here.

Il problema è che il mio primo metodo conterrà un ciclo e il secondo metodo deve contenere un break :

def first_small(dct, second_method):
    # Initial code
    # ...
    for i in dct:
        # More code
        # ...
        for j in dct[i]:
            second_method()


def second_small(j):

    # Plenty of code
    # ...
    # ...
    # and a break
    if j == 'something':
        break    
    # Inner code ended here.

second_small() genererebbe un SyntaxError: 'break' outside loop .

Per risolvere il problema, posso sostituire break in second_small() con un'eccezione personalizzata e rendere first_small() gestire quell'eccezione e interrompere il ciclo quando lo trova:

def first_small(dct, second_method):
    # Initial code
    # ...
    for i in dct:
        # More code
        # ...
        for j in dct[i]:
            try:
                second_method(j=j)
            except MyException:
                break


def second_small(j):

    # Inner code
    # ...
    # ...
    # and a break
    if j == 'something':
        raise MyException
    # Inner code ended here.

Tuttavia, non sono così sicuro che questo sia il modo più pulito per riuscirci.

Domanda:
Come dovrei dividere un metodo in altri due, in cui il primo metodo conterrà un ciclo e il secondo deve interrompere quel ciclo?

    
posta Fermi paradox 23.05.2015 - 10:04
fonte

1 risposta

7

Dimentica il ciclo esterno per un momento e pensa al significato del tuo metodo second_small , l'astrazione che rappresenta (presumo nel tuo codice reale, hai scelto un nome più significativo). Quindi quello che fai in quel metodo dovrebbe dipendere da cosa

 if j == 'something':
     ...

significa, in contrasto con quell'astrazione. Ad esempio, se j == 'something' è un caso di errore reale, genera un'eccezione. Se significa "Ho trovato con successo il risultato di una ricerca", utilizza un valore di ritorno booleano e restituisce True . Se significa "impossibile trovarlo", restituisci False . Se significa "convalida riuscita", restituisce True .

Un valore di ritorno booleano potrebbe essere anche l'alternativa migliore se la condizione significa "potrebbe essere un errore, non è sicuro, solo il chiamante può decidere". Un booleano è probabilmente l'alternativa sbagliata se devi fornire qualche tipo di messaggio di errore.

Dovrebbe essere chiaro in caso di utilizzo di un booleano, il tuo codice sarà finalmente simile a questo:

 for j in dct[i]:
      if second_method(j):
            break

def second_method(j):
    # ...
    if j == 'something':
        return True
    # ...
    
risposta data 23.05.2015 - 10:19
fonte

Leggi altre domande sui tag