简体   繁体   中英

Repeat an iteration in loop if error occurs

Is there a command such as break and continue which could repeat recent iteration?

For example, when exception is thrown.

for i in range(0,500):
    try:
        conn = getConnection(url+str(i))
        doSomething(conn)
    except:
        repeat

Let's have an iteration where i variable's value is 6 . During this iteration some connection error occurred. I want to repeat this iteration.

Is there a command which can do that?

Of course I can do this:

i=0
while i!=500:
    try:
        conn = getConnection(url+str(i))
        doSomething(conn)
        i+=1
    except:
        pass

No, there is no command to "rewind" a for-loop in Python.

You could use a while True: loop inside the for-loop:

for i in range(500):
    while True:
        try:
            conn = getConnection(url+str(i))
            doSomething(conn)
        except Exception: # Replace Exception with something more specific.
            continue
        else:
            break

or without the else: :

for i in range(500):
    while True:
        try:
            conn = getConnection(url+str(i))
            doSomething(conn)
            break
        except Exception: # Replace Exception with something more specific.
            continue

But I personally think that your proposed solution is better because it avoids an indentation level.

for i in range(500):
    while True
        try:
            conn = getConnection(url+str(i))
            break
        except Exception: # still allows to quit with KeyboardInterrupt
            continue
    do_your_stuff()

This looks bit risky, however, you should at least enable some logging inside a while block.

If you expect to use it in more places, you might write a simple decorator:

def keep_trying(fn, *args, **kwargs):
    def inner(*args, **kwargs):
        while True:
            try:
                return fn(*args, **kwargs)
            except Exception:
                continue
    return inner

# later you can use it simple like this:
for i in range(500):
    conn = keep_trying(getConnection)(url+str(i))

You can use generators :

def process_connections(n_connections, url, max_tries=50):
    i = 0
    try_count = 0
    while i < n_connections:
        try:
            conn = getConnection(url+str(i))
            yield conn
        except:
            try_count += 1
            if try_count > max_tries:
                raise Exception("Unable to connect after %s tries" % max_tries)
        else:
            i += 1 # increments only if no exception 

And you perform your operations :

for conn in process_connections(500, url):
    do_something(conn)

Why not just use an if statement?

n=6
i=0
while i!=500:
    failed = False;
    try:
        conn = getConnection(url+str(i))
        doSomething(conn)
        i+=1
    except:
        #handle error
        failed = True;

    #try again if n-th case failed first time
    if(i == n and failed):
        try:
            conn = getConnection(url+str(i))
            doSomething(conn)
        except:
            #handle error

You can use nested for loops to put a cap on the number of times you retry the operation. This is bascially the sam as @PierreAlex's generator answer but without the extra function definition.

for i in range(500):
    for retry in range(10):
        try:
            conn = getConnection(url+str(i))
            doSomething(conn)
        except Exception: # Replace Exception with something more specific.
            time.sleep(1)
    else:
        print "iteration", i, "failed"

Here is one. You would need to add a logging or alert system to let you know that something is stuck:

state = "" #state of the loop

# If there is no error continue. If there is error, remain in loop
while True:
  if state != "error": 
    try:
      1/0 # command
      break # no error so break out of loop
    except:
      state = "error" #declare error so maintain loop
      continue
  elif state == "error": # maintain loop
    continue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM