예외 후에 다시 시도하는 방법?
로 시작하는 루프가 for i in range(0, 100)
있습니다. 일반적으로 올바르게 실행되지만 네트워크 상태로 인해 실패하는 경우가 있습니다. 현재 나는 실패 continue
했을 때 except 절 에 있도록 설정했습니다 (에 대한 다음 숫자로 계속 i
).
동일한 번호를 다시 할당 i
하고 루프의 실패한 반복을 다시 실행할 수 있습니까?
를 수행 while True
루프를 들어, 넣어 당신의 내부에 try
그에서 코드 내부 및 휴식 while
코드가 성공에만 루프.
for i in range(0,100):
while True:
try:
# do stuff
except SomeSpecificException:
continue
break
재시도 횟수를 제한하여 특정 항목에 문제가있는 경우 다음 항목으로 계속 진행할 수 있습니다.
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.
다시 시도 패키지는 실패 코드 블록을 재 시도 할 수있는 좋은 방법입니다.
예를 들면 다음과 같습니다.
@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()
Python Decorator Library 와 비슷한 것이 있습니다 .
예외를 테스트하지 않고 반환 값을 명심하십시오. 데코 레이팅 된 함수가 True를 반환 할 때까지 재 시도합니다.
약간 수정 된 버전이 트릭을 수행해야합니다.
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
My version is similar to several of the above, but doesn't use a separate while
loop, and re-raises the latest exception if all retries fail. Could explicitly set err = None
at the top, but not strictly necessary as it should only execute the final else
block if there was an error and therefore err
is set.
Using while and a counter:
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
You can use Python retrying package. Retrying
It is written in Python to simplify the task of adding retry behavior to just about anything.
If you want a solution without nested loops and invoking break
on success you could developer a quick wrap retriable
for any iterable. Here's an example of a networking issue that I run into often - saved authentication expires. The use of it would read like this:
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
I use following in my codes,
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
i recently worked with my python on a solution to this problem and i am happy to share it with stackoverflow visitors please give feedback if it is needed.
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}')
Here's my idea on how to fix this:
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)
increment your loop variable only when the try clause succeeds
참고URL : https://stackoverflow.com/questions/2083987/how-to-retry-after-exception
'Programing' 카테고리의 다른 글
모든 하위 디렉토리에 대해 git pull을 실행하십시오. (0) | 2020.04.29 |
---|---|
탭 레이아웃 탭 선택 (0) | 2020.04.29 |
어떤 종류의 예외와 함께 RSpec의 should_raise를 사용하는 방법? (0) | 2020.04.29 |
타임 스탬프를 읽을 수있는 날짜 / 시간 PHP로 변환 (0) | 2020.04.29 |
절대 파일 경로를 포함하는 문자열에서 파일 이름을 어떻게 얻습니까? (0) | 2020.04.29 |