Обработка исключений - запустить функцию снова, вложив или зацикливаясь? - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть функция, которая часто выдает исключение (SSH более 3g).

Я хотел бы продолжать пытаться запускать function() каждые 10 секунд, пока это не удастся (не выдает исключение).

На мой взгляд, есть два варианта:

Вложение:

def nestwrapper():
    try:
        output = function()
    except SSHException as e:
        # Try again
        sleep(10)
        return nestwrapper()
    return output

Цикл: (обновлено)

Было отмечено, что предыдущий код цикла был довольно ненужным.

def loopwrapper():
    while True:
        try:
            return function()
        except SSHException as e:
            sleep(10)

Есть ли предпочтительный способ сделать это?

Есть ли проблема с вложенностью и стеком исключений?

Ответы [ 3 ]

3 голосов
/ 10 февраля 2012

Я бы нашел цикл, который будет чище и эффективнее.Если это задание автоматизации, рекурсивный метод может достичь предела рекурсии Python (по умолчанию 1000 iirc, можно проверить с помощью sys.getrecursionlimit()).

Не использовать status is False для выражения, потому чтосравнение идентичности.Используйте while not status.

Возможно, я бы тоже реализовал это немного по-другому, потому что я не вижу необходимости в двух разных функциях:

def function_with_retries():
  while True:
    try:
      output = function()
    except SSHException:
      sleep(10)
    else:
      return output
1 голос
/ 10 февраля 2012

Я не уверен, что чертовски много смысла специально переносить вызов функции дважды. исключение, вероятно, является разумным, и вы переходите к дополнительному этапу повторения этого конкретного исключения. Я имею в виду, что попытка / исключение довольно тесно связана с циклом повторной попытки.

Я обычно так делаю:

def retry_something():
    while True:
        try:
            return something()
        except SomeSpecialError:
            sleep(10)

while True: - это действительно то, что вы делаете, вы собираетесь зацикливаться вечно, или, скорее, до тех пор, пока вам действительно не удастся набрать something(), а затем вернуться Больше нет необходимости в булевом флаге успеха, на что указывает обычный случай оператора return (который вежливо экранирует цикл).

0 голосов
/ 10 февраля 2012

Сохраняйте это простым.

function looper(f):
    while 1:
        try:
            return f()
        except SSHException, e:
            sleep(10)

output = looper(<function to call>)
...