The itertools.iter_except
recepty oddaje tę ideę „nazywając wielokrotnie funkcję dopóki jest wyjątek”. Jest podobny do zaakceptowanej odpowiedzi, ale zamiast tego przepis podaje iterator.
Od Przepisy:
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
Można oczywiście realizować ten drugi kod bezpośrednio. Dla wygody używam oddzielnej biblioteki, more_itertools
, która implementuje ten przepis dla nas (opcjonalnie).
przykład:
import more_itertools as mit
list(mit.iter_except([0, 1, 2].pop, IndexError))
# [2, 1, 0]
Tutaj pop
Sposób (a biorąc pod uwagę funkcji) jest wywoływana dla każdej iteracji przedmiotu do czasu aż w IndexError
jest podniesiony.
Twoim przypadku, biorąc pod uwagę niektóre connect_function
i oczekiwany błąd, można dokonać iterator, który wywołuje wielokrotnie funkcję aż wyjątek jest podniesiona, np
mit.iter_except(connect_function, ConnectionError)
W tym momencie, traktować go jak każdy inny iterator przez zapętlenie go lub wywołanie next()
.
Błąd ... co się stanie, gdy zdalny serwer zginie? Czy to się stanie, zużywając 100% rdzenia procesora? – user9876
continue powinno być w innym miejscu i włamać się z wyjątkiem. Czy to literówka? –
@aand: Nie. Jeśli wystąpi wyjątek, chce spróbować jeszcze raz (czytaj: 'kontynuuj'), ale jeśli nie ma wyjątku, chce coś (naszkicować komentarzem) i wydostać się z tego dziwnego nadużycia pętla. ("else" jest wykonywany, jeśli nie ma wyjątku, czy brakujący element?) – delnan