Python игнорировать исключения и вернуться туда, где я был - PullRequest
13 голосов
/ 29 сентября 2010

Я знаю, как использовать приведенный ниже код, чтобы игнорировать определенное исключение, но как позволить коду вернуться туда, где он получил исключение, и продолжить выполнение?Скажите, если в do_something1 возникает исключение «Exception», как заставить код игнорировать его и продолжать завершать do_something1 и обрабатывать do_something2?Мой код просто перейти к блоку finally после прохода процесса, кроме блока.Пожалуйста, сообщите, спасибо.

try:
    do_something1
    do_something2
    do_something3
    do_something4
except Exception:
    pass
finally:
    clean_up

РЕДАКТИРОВАТЬ: Спасибо за ответ.Теперь я знаю, как правильно это сделать.Но вот еще один вопрос, могу ли я просто проигнорировать конкретное исключение (скажем, знаю ли я номер ошибки).Возможен ли приведенный ниже код?

try:
    do_something1
except Exception.strerror == 10001:
    pass

try:
    do_something2
except Exception.strerror == 10002:
    pass
finally:
    clean_up

do_something3
do_something4

Ответы [ 6 ]

9 голосов
/ 29 сентября 2010

Здесь почти не хватает исключений.

Если в первом операторе возникло исключение, система находится в неопределенном состоянии, и вы должны рассматривать следующий оператор как небезопасный для выполнения.

Если вы знаете, какие операторы могут потерпеть неудачу и как они могут потерпеть неудачу, вы можете использовать обработку исключений, чтобы специально устранить проблемы, которые могут возникнуть с конкретным блоком операторов, прежде чем переходить к следующему разделу.

Таким образом, единственный реальный ответ - это обработка исключений вокруг каждого набора операторов, которые вы хотите рассматривать как атомарные

9 голосов
/ 29 сентября 2010

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

try:
    do_something1
except TheExceptionTypeThatICanHandleError, e:
    if e.strerror != 10001:
        raise
finally:
     clean_up

Обратите также внимание, что для каждого оператора try требуется свое собственное предложение finally, если вы хотите, чтобы оно было.Он не присоединится к предыдущему оператору try.Оператор raise, не имеющий ничего другого, является правильным способом для повторного вызова последнего исключения.Не позволяйте никому говорить вам иначе.


То, что вы хотите - это продолжения, которые Python не предоставляет изначально.Кроме того, ответ на ваш вопрос зависит от того, что именно вы хотите сделать.Если вы хотите, чтобы do_something1 продолжался независимо от исключений, тогда it должен будет перехватывать исключения и игнорировать их сам.

, если вы просто хотите, чтобы do_something2 происходил независимо от того, do_something1 завершено, вам нужен отдельный оператор try для каждого.

try:
   do_something1()
except:
   pass

try:
   do_something2()
except:
   pass

и т. Д.Если вы можете предоставить более подробный пример того, что именно вы хотите сделать, то есть большая вероятность, что я или кто-то умнее меня может либо помочь вам, либо (что более вероятно) отговорить вас от этого и предложить более разумныйальтернатива.

7 голосов
/ 29 сентября 2010

Нет прямого способа возврата кода внутрь блока try-кроме. Однако, если вы пытаетесь выполнить эти различные независимые действия и продолжаете их выполнять при сбое (без копирования / вставки блока try / Кроме), вам нужно написать что-то вроде этого:

actions = (
    do_something1, do_something2, #...
    )
for action in actions:
    try:
        action()
    except Exception, error:
        pass
2 голосов
/ 29 сентября 2010

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

work = [lambda: dosomething1(args), dosomething2, lambda: dosomething3(*kw, **kwargs)]

for each in work:
    try:
        each()
    except:
       pass

cleanup()
2 голосов
/ 29 сентября 2010

Исключения обычно возникают, когда выполнение задачи не может быть выполнено способом, предусмотренным кодом по определенным причинам. Это обычно поднимается как исключения. Исключения должны обрабатываться и не игнорироваться. Вся идея исключения состоит в том, что программа не может продолжать работу в нормальном режиме без ненормальных результатов.

Что если вы напишите код, чтобы открыть файл и прочитать его? Что делать, если этот файл не существует?

Гораздо лучше поднять исключение. Вы не можете прочитать файл, где его нет. Что вы можете сделать, это обработать исключение, сообщить пользователю, что такого файла не существует. Какие преимущества можно получить, если продолжить чтение файла, если файл вообще не открывается.

Фактически вышеупомянутые ответы, предоставленные Аароном, работают по принципу обработки ваших исключений.

1 голос
/ 29 сентября 2010

Я недавно опубликовал это как ответ на другой вопрос.Здесь у вас есть функция, которая возвращает функцию, которая игнорирует ("ловушки") указанные исключения при вызове любой функции.Затем вы вызываете нужную функцию косвенно через «ловушку».

def maketrap(*exceptions):
    def trap(func, *args, **kwargs):
        try:
            return func(*args, **kwargs)
        except exceptions:
            return None
    return trap

# create a trap that ignores all exceptions
trapall = maketrap(Exception) 

# create a trap that ignores two exceptions
trapkeyattrerr = maketrap(KeyError, AttributeError)

# Now call some functions, ignoring specific exceptions
trapall(dosomething1, arg1, arg2)
trapkeyattrerr(dosomething2, arg1, arg2, arg3)

В общем, я с теми, кто говорит, что игнорирование исключений - плохая идея, но если вы сделаете это, вы должны быть столь же конкретнынасколько возможно, какие исключения, по вашему мнению, может выдержать ваш код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...