Подтвердить что ты не робот

Исключение catch для python и продолжить попытку блокировки

Можно ли вернуться к выполнению try-блока после исключения? (Цель состоит в том, чтобы написать меньше) Например:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

против

try:
    do_smth1()
    do_smth2()
except:
    ??? # magic word to proceed to do_smth2() if there was exception in do_smth1
4b9b3361

Ответ 1

Нет, вы не можете этого сделать. Это так, как у Python есть свой синтаксис. Как только вы выходите из блока try из-за исключения, нет пути назад.

А как насчет for-loop?

funcs = do_smth1, do_smth2

for func in funcs:
    try:
        func()
    except Exception:
        pass  # or you could use 'continue'

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

Ответ 2

В то время как другие ответы и принятые являются правильными и должны выполняться в реальном коде, просто для полноты и юмора, вы можете попробовать fuckitpy (https://github.com/ajalt/fuckitpy).

Ваш код можно изменить на следующее:

@fuckitpy
def myfunc():
    do_smth1()
    do_smth2()

Тогда вызов myfunc() вызовет do_smth2(), даже если в do_smth1())

есть исключение,

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

Ответ 3

Вы можете достичь того, чего хотите, но с другим синтаксисом. Вы можете использовать блок "finally" после try/except. Таким образом, python будет выполнять блок кода независимо от того, было ли исключено исключение.

Вот так:

try:
    do_smth1()
except:
    pass
finally:
    do_smth2()

Но если вы хотите выполнить do_smth2(), только если исключение не было выбрано, используйте блок "else":

try:
    do_smth1()
except:
    pass
else:
    do_smth2()

Вы также можете их смешивать в предложении try/except/else/finally. Получайте удовольствие!

Ответ 4

Вы можете выполнять итерацию через свои методы...

for m in [do_smth1, do_smth2]:
    try:
        m()
    except:
        pass

Ответ 5

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

def consume_exceptions(gen):
    action = next(gen)
    while True:
        try:
            result = action()
        except Exception:
            # if the action fails, send a sentinel
            result = None

        try:
            action = gen.send(result)
        except StopIteration:
            # if the generator is all used up, result is the return value.
            return result

генератор, который был бы совместим с этим, будет выглядеть так:

def do_smth1():
    1 / 0

def do_smth2():
    print "YAY"

def do_many_things():
    a = yield do_smth1
    b = yield do_smth2
    yield "Done"
>>> consume_exceptions(do_many_things())
YAY

Обратите внимание, что do_many_things() не вызывает do_smth*, он просто возвращает их, а consume_exceptions вызывает их от своего имени

Ответ 6

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

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception

Ответ 7

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

def live_dangerously(fn, *args, **kw):
    try:
        return fn(*args, **kw)
    except Exception:
        pass

live_dangerously(do_smth1)
live_dangerously(do_smth2)

Но, как отметили другие ответы, наличие нулевого значения except обычно является признаком того, что с вашим кодом что-то не так.