25

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
2
  • 1
    There's no syntax thats builtin to python that will allow you to do that if thats what you're asking. You can always just retry the same function in the except clause though Commented Dec 1, 2014 at 21:22
  • 1
    You can use generators, yielding each successful connection Commented Dec 1, 2014 at 21:32

7 Answers 7

24

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.

Sign up to request clarification or add additional context in comments.

3 Comments

bare except makes it impossible to stop this program without kill -9.
Yea, I was focusing on the loops and overlooked that. Fixed.
All fine and dandy but this would entail quite a serious change in how iterators are implemented in python
4
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))

Comments

2

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)

1 Comment

Is it possible to have an infinite loop if there is something wrong with a connection?
1

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"

Comments

0

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

Comments

0

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

Comments

0

Here's a different approach that returns the function with arguments in case of exception:

retries = 0
max_retries = 5

def x(a, b):
  global retries
  global max_retries
  print(retries)
  try:
    d = a / b
  except:
    retries += 1
    if retries >= max_retries:
      return {}
    else:
      return x(a, b)

a = 0
b = 0
y = x(a, b)
print(y)

0
1
2
3
4
{}

Demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.