Повторите итерацию в цикле, если произошла ошибка

есть ли такая команда, как break и continue что может повторить недавнюю итерацию?

например, при возникновении исключения.

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

давайте сделаем итерацию где i значение переменной -6. Во время этой итерации произошла ошибка соединения. Я хочу повторить эту итерацию.

есть ли команда, которая может это сделать?

конечно, я могу сделать это:

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

5 ответов


нет, нет команды для "перемотки" цикла for в Python.

вы могли бы использовать while True: петля внутри 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

и без 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

но я лично думаю, что ваше предлагаемое решение лучше, потому что оно позволяет избежать уровня отступа.


Вы можете использовать генераторы :

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 

и вы выполняете свои операции:

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

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()

это выглядит немного рискованно, однако, вы должны по крайней мере включить некоторое ведение журнала внутри while блок.

Если вы ожидаете использовать его в других местах, вы можете написать простой декоратор:

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))

почему бы просто не использовать if заявление?

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

вы можете использовать вложенные циклы for, чтобы ограничить количество раз вы повторите операцию. Это в основном ответ генератора sam as @PierreAlex, но без определения дополнительной функции.

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"