Исключение 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
Ответы
Ответ 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
обычно является признаком того, что с вашим кодом что-то не так.