How to write multiple try statements in one block in python?
Solution 1
I'd write a quick wrapper function first()
for this.
usage: value = first([f1, f2, f3, ..., fn], default='All failed')
#!/usr/bin/env
def first(flist, default=None):
""" Try each function in `flist` until one does not throw an exception, and
return the return value of that function. If all functions throw exceptions,
return `default`
Args:
flist - list of functions to try
default - value to return if all functions fail
Returns:
return value of first function that does not throw exception, or
`default` if all throw exceptions.
TODO: Also accept a list of (f, (exceptions)) tuples, where f is the
function as above and (exceptions) is a tuple of exceptions that f should
expect. This allows you to still re-raise unexpected exceptions.
"""
for f in flist:
try:
return f()
except:
continue
else:
return default
# Testing.
def f():
raise TypeError
def g():
raise IndexError
def h():
return 1
# We skip two exception-throwing functions and return value of the last.
assert first([f, g, h]) == 1
assert first([f, g, f], default='monty') == 'monty'
Solution 2
If you really don't care about the exceptions, you could loop over cases until you succeed:
for fn in (do, do2, do3, do4):
try:
fn()
break
except:
continue
This at least avoids having to indent once for every case. If the different functions need different arguments you can use functools.partial to 'prime' them before the loop.
Solution 3
It seems like a really odd thing to want to do, but I would probably loop over the functions and break out when there were no exception raised:
for func in [do, do2, do3]:
try:
func()
except Exception:
pass
else:
break
Solution 4
Here is the simplest way I found, just embed the try under the previous except.
try:
do()
except:
try:
do2()
except:
do3()
Solution 5
You should specify the type of the exception you are trying to catch each time.
try:
do()
except TypeError: #for example first one - TypeError
do_2()
except KeyError: #for example second one - KeyError
do_3()
and so on.
alwbtc
Updated on July 09, 2022Comments
-
alwbtc almost 2 years
I want to do:
try: do() except: do2() except: do3() except: do4()
If do() fails, execute do2(), if do2() fails too, exceute do3() and so on.
best Regards
-
alwbtc over 11 yearsIf I don't know the type of the exception?
-
BrenBarn over 11 years@alwbic: If you don't know the type of the exception, you don't know how to handle the exception.
-
alexvassel over 11 years@alwbic I am really sure that you must know what type(s) of exception(s) do you expect.
-
alwbtc over 11 yearsI don't agree with you. I know that my statement will fail, but i don't know in which order they will fail. But I know what to do if it fails.
-
alexvassel over 11 years@alwbic: It is just a bad practice "Do something if something fails", you don't now why it fails.
-
Kenan Banks over 11 years
pass
should becontinue
perhaps? Works as written butcontinue
is semantically clearer. -
Fredrik Håård over 11 years@Triptych True, that does signal intent better. Edited answer.
-
Thierry Lathuille almost 7 yearsThis doesn't answer the question at all!
-
AbstProcDo over 5 yearsCreat, but what's else here for? it seem redundant here.
-
gaqzi over 5 yearsThe
else
will only execute when there isn't an exception. If there's an exception the for will continue whereas if there wasn't an exception thebreak
will execute. :) A lot of statements in Python takes anelse
with the intention of "if everything went well, then do this". See the documentation for thetry
statement: docs.python.org/3/reference/compound_stmts.html#try -
Aaron John Sabu almost 4 yearsI did the same thing but can't it be made more compact?
-
aerijman almost 4 years@alwbic. I agree with you and you can do
except Exception: pass
. Something I always do when I develop isexcept Exception as e: print(str(e))
to know what was the error. -
Chris over 2 yearsI laughed so hard at this answer, thanks for making my day