Jak spróbować ponownie po wyjątku?
Mam pętlę zaczynającą się od for i in range(0, 100)
. Zwykle działa poprawnie, ale czasami zawodzi z powodu warunków sieciowych. Obecnie mam go ustawiony tak, że po niepowodzeniu będzie continue
w klauzuli except(dalej do następnego numeru dla i
).
Czy jest możliwe, abym ponownie przypisał ten sam numer do i
i ponownie uruchomił nieudaną iterację pętli?
14 answers
Wykonaj while True
wewnątrz pętli for, włóż kod try
do środka i przerwij tę pętlę while
tylko wtedy, gdy twój Kod się powiedzie.
for i in range(0,100):
while True:
try:
# do stuff
except SomeSpecificException:
continue
break
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-02 17:03:00
Wolę ograniczyć liczbę powtórzeń, tak, że jeśli pojawi się problem z danym przedmiotem, w końcu przejdziesz do następnego, a więc:
for i in range(100):
for attempt in range(10):
try:
# do thing
except:
# perhaps reconnect, etc.
else:
break
else:
# we failed all the attempts - deal with the consequences.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 15:03:37
Pakiet retrying jest dobrym sposobem na ponowne spróbowanie bloku kodu po niepowodzeniu.
Na przykład:
@retry(wait_random_min=1000, wait_random_max=2000)
def wait_random_1_to_2_s():
print "Randomly wait 1 to 2 seconds between retries"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-18 12:29:43
Tutaj jest rozwiązanie podobne do innych, ale spowoduje to powstanie wyjątku, jeśli nie uda mu się wykonać określonej liczby lub powtórzeń.
tries = 3
for i in range(tries):
try:
do_the_thing()
except KeyError as e:
if i < tries - 1: # i is zero indexed
continue
else:
raise
break
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-17 17:34:02
Bardziej "funkcjonalne" podejście bez używania brzydkich pętli while:
def tryAgain(retries=0):
if retries > 10: return
try:
# Do stuff
except:
retries+=1
tryAgain(retries)
tryAgain()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-28 20:46:42
Najczystszym sposobem byłoby jawne ustawienie i
. Na przykład:
i = 0
while i < 100:
i += 1
try:
# do stuff
except MyException:
continue
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 23:28:54
Jest coś podobnego w Python Decorator Library.
Należy pamiętać, że nie testuje wyjątków, ale zwraca wartość. Powtarza się, dopóki funkcja dekorowana nie zwróci True.
Lekko zmodyfikowana wersja powinna załatwić sprawę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 16:22:50
Using recursion
for i in range(100):
def do():
try:
## Network related scripts
except SpecificException as ex:
do()
do() ## invoke do() whenever required inside this loop
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-31 12:19:14
Ogólne rozwiązanie z limitem czasu:
import time
def onerror_retry(exception, callback, timeout=2, timedelta=.1):
end_time = time.time() + timeout
while True:
try:
yield callback()
break
except exception:
if time.time() > end_time:
raise
elif timedelta > 0:
time.sleep(timedelta)
Użycie:
for retry in onerror_retry(SomeSpecificException, do_stuff):
retry()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-17 12:51:31
Używanie while I licznika:
count = 1
while count <= 3: # try 3 times
try:
# do_the_logic()
break
except SomeSpecificException as e:
# If trying 3rd time and still error??
# Just throw the error- we don't have anything to hide :)
if count == 3:
raise
count += 1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-31 11:57:34
Możesz użyć Pythona retrying package. Retrying
Jest napisany w Pythonie, aby uprościć zadanie dodawania zachowania retry do niemal wszystkiego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 17:13:08
Jeśli chcesz mieć rozwiązanie bez zagnieżdżonych pętli i wywoływania {[1] } po sukcesie, możesz stworzyć szybkie zawijanie retriable
dla każdego iterowalnego. Oto przykład problemu z siecią, na który często wpadam-zapisane uwierzytelnianie wygasa. Jego użycie brzmiałoby tak:
client = get_client()
smart_loop = retriable(list_of_values):
for value in smart_loop:
try:
client.do_something_with(value)
except ClientAuthExpired:
client = get_client()
smart_loop.retry()
continue
except NetworkTimeout:
smart_loop.retry()
continue
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 21:28:48
Oto mój pomysł jak to naprawić:
j = 19
def calc(y):
global j
try:
j = j + 8 - y
x = int(y/j) # this will eventually raise DIV/0 when j=0
print("i = ", str(y), " j = ", str(j), " x = ", str(x))
except:
j = j + 1 # when the exception happens, increment "j" and retry
calc(y)
for i in range(50):
calc(i)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 23:47:23
Zwiększ zmienną pętli tylko wtedy, gdy klauzula try powiedzie się
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-18 09:34:27