Выполнить (часть) блок try после блока кроме - PullRequest
2 голосов
/ 19 ноября 2010

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

Пример:

[...]
try:
 do.this()
 do.that()
 [...]
except:
 foo.bar()
[...]

do.this() вызвать исключение, управляемое foo.bar(), тогда я хотел бы выполнить код из do.that(). Я знаю, что здесь нет оператора GOTO, но, возможно, какой-то хак или обходной путь!

Спасибо!

Ответы [ 8 ]

5 голосов
/ 19 ноября 2010

A try... except... блок перехватывает one исключение.Вот для чего это.Он выполняет код внутри попытки, и, если возникает исключение, обрабатывает его в исключении.Вы не можете вызывать несколько исключений внутри попытки.

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

Вы должны сделать:

try:
    do.this()
except FailError:
    clean.up()

try:
    do.that()
except FailError:
    clean.up()

, чтобы любое исключение вы вызывалиобрабатывается явно.

2 голосов
/ 19 ноября 2010

Использовать блок finally? Я что-то упустил?

   [...] 
    try: 
     do.this() 
    except: 
     foo.bar() 
    [...] 
    finally:
     do.that()
     [...] 
1 голос
/ 19 ноября 2010
fcts = [do.this, do.that]
for fct in fcts:
    try:
        fct()
    except:
        foo.bar()
1 голос
/ 19 ноября 2010

Одна возможность состоит в том, чтобы написать код таким образом, чтобы вы могли повторно выполнить его все, когда условие ошибки было решено, например ::

while 1:
   try:
      complex_operation()
   except X:
      solve_problem()
      continue
   break
1 голос
/ 19 ноября 2010

Если вам всегда нужно выполнить foo.bar(), почему бы просто не переместить его после блока try / Кроме?Или, может быть, даже в finally: блок.

0 голосов
/ 19 ноября 2010

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

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

def myOp(fileRetriever):

    f = acquireFile()
    if not f:
        f = fileRetriever()

    # continue with your stuff...

    f2 = acquireAnotherFile()
    if not f2:
        f2 = fileRetriever()

    # more stuff...


myOp(magicalCallback)

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

0 голосов
/ 19 ноября 2010

Это не хорошо масштабируется, но для небольших блоков кода вы можете использовать классический конечный автомат:

states = [do.this, do.that]
state = 0
while state < len(states):
    try:
        states[state]()
    except:
        foo.bar()
    state += 1
0 голосов
/ 19 ноября 2010

Вам нужно два блока try, по одному для каждого оператора в вашем текущем блоке try.

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