Le ricette itertools.iter_except
racchiude l'idea di "chiamare una funzione più volte fino a quando viene generata un'eccezione". È simile alla risposta accettata, ma la ricetta fornisce invece un iteratore.
Dalle ricette:
def iter_except(func, exception, first=None):
""" Call a function repeatedly until an exception is raised."""
try:
if first is not None:
yield first() # For database APIs needing an initial cast to db.first()
while True:
yield func()
except exception:
pass
Si può certamente implementare direttamente il secondo codice. Per comodità, io uso una libreria separata, more_itertools
, che implementa questa ricetta per noi (opzionale).
Esempio:
import more_itertools as mit
list(mit.iter_except([0, 1, 2].pop, IndexError))
# [2, 1, 0]
Qui il pop
metodo (o data funzione) viene chiamata per ogni iterazione dell'oggetto Lista finché un IndexError
viene sollevata.
Per il vostro caso, dato un certo connect_function
e di errore previsto, si può fare un iteratore che chiama ripetutamente la funzione fino a quando viene sollevata un'eccezione, ad esempio:
mit.iter_except(connect_function, ConnectionError)
A questo punto, trattarlo come qualsiasi altro iteratore collegandoci sopra o chiamando next()
.
Err ... cosa succede quando il server remoto muore? Sarà seduto lì consumando il 100% del core della CPU? – user9876
continuare dovrebbe essere in altro e irrompere tranne. È un errore di battitura? –
@aand: No. Se si verifica un'eccezione, vuole riprovare (leggi: 'continua'), ma se non si verifica alcuna eccezione, vuole fare alcune cose (delineato da un commento) e uscire da quello strano abuso di un ciclo. ('else' viene eseguito se non si verifica alcuna eccezione, è il pezzo mancante?) – delnan