我有一个以for i in range(0, 100)
开头的循环。正常情况下,它可以正常运行,但有时由于网络条件而失败。目前,我已对其进行设置,以便在失败时将在except子句中显示为continue
(继续进行i
的下一个数字)。
我是否可以将相同的数字重新分配给i
并再次执行循环的失败迭代?
在for循环内执行while True
,将您的try
代码放入其中,仅在代码成功后才从该while
循环中中断。
for i in range(0,100):
while True:
try:
# do stuff
except SomeSpecificException:
continue
break
for _ in range(5):
try:
# replace this with something that may fail
raise ValueError("foo")
# replace Exception with a more specific exception
except Exception as e:
err = e
continue
# no exception, continue remainder of code
else:
break
# did not break the for loop, therefore all attempts
# raised an exception
else:
raise err
我的版本与上述几种类似,但是不使用单独的while
循环,并且如果所有重试均失败,则会重新引发最新的异常。可以在顶部显式设置err = None
,但并非绝对必要,因为只有在出现错误并因此设置了else
时,才应执行最后的err
块。
同时使用和计数器:
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
您可以使用Python重试包。Retrying
它是用Python编写的,以简化将重试行为添加到几乎所有内容的任务。
如果您想要一个没有嵌套循环且成功调用break
的解决方案,则可以为所有可迭代对象开发一个快速包装retriable
。这是我经常遇到的网络问题的示例-保存的身份验证过期。它的使用将如下所示:
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
我在代码中使用以下代码,
for i in range(0, 10):
try:
#things I need to do
except ValueError:
print("Try #{} failed with ValueError: Sleeping for 2 secs before next try:".format(i))
time.sleep(2)
continue
break
我最近与我的python合作解决了这个问题,很高兴与stackoverflow访问者分享它,如果需要的话,请提供反馈。
print("\nmonthly salary per day and year converter".title())
print('==' * 25)
def income_counter(day, salary, month):
global result2, result, is_ready, result3
result = salary / month
result2 = result * day
result3 = salary * 12
is_ready = True
return result, result2, result3, is_ready
i = 0
for i in range(5):
try:
month = int(input("\ntotal days of the current month: "))
salary = int(input("total salary per month: "))
day = int(input("Total Days to calculate> "))
income_counter(day=day, salary=salary, month=month)
if is_ready:
print(f'Your Salary per one day is: {round(result)}')
print(f'your income in {day} days will be: {round(result2)}')
print(f'your total income in one year will be: {round(result3)}')
break
else:
continue
except ZeroDivisionError:
is_ready = False
i += 1
print("a month does'nt have 0 days, please try again")
print(f'total chances left: {5 - i}')
except ValueError:
is_ready = False
i += 1
print("Invalid value, please type a number")
print(f'total chances left: {5 - i}')
这是我的解决方法:
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)
仅在try子句成功时才增加循环变量
我更喜欢限制重试次数,这样,如果该特定项目有问题,您最终将继续进行下一个,因此:
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.
retrying package是在失败时重试代码块的好方法。
例如:
@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")
这里有一个与其他解决方案相似的解决方案,但是如果未按规定的次数或重试次数成功,它将引发异常。
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
更“实用”的方法,而不使用那些难看的while循环:
def tryAgain(retries=0):
if retries > 10: return
try:
# Do stuff
except:
retries+=1
tryAgain(retries)
tryAgain()
最清楚的方法是显式设置i
。例如:
i = 0
while i < 100:
i += 1
try:
# do stuff
except MyException:
continue
使用递归
for i in range(100):
def do():
try:
## Network related scripts
except SpecificException as ex:
do()
do() ## invoke do() whenever required inside this loop
具有超时的通用解决方案:
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)
用法:
for retry in onerror_retry(SomeSpecificException, do_stuff):
retry()