[python] python catch exception and continue try block

Can I return to executing try-block after exception occurs? (The goal is to write less) For Example:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

vs

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

This question is related to python exception

The answer is


No, you cannot do that. That's just the way Python has its syntax. Once you exit a try-block because of an exception, there is no way back in.

What about a for-loop though?

funcs = do_smth1, do_smth2

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

Note however that it is considered a bad practice to have a bare except. You should catch for a specific exception instead. I captured for Exception because that's as good as I can do without knowing what exceptions the methods might throw.


You can achieve what you want, but with a different syntax. You can use a "finally" block after the try/except. Doing this way, python will execute the block of code regardless the exception was thrown, or not.

Like this:

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

But, if you want to execute do_smth2() only if the exception was not thrown, use a "else" block:

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

You can mix them too, in a try/except/else/finally clause. Have fun!


special_func to avoid try-except repetition:

def special_func(test_case_dict):
    final_dict = {}
    exception_dict = {}

    def try_except_avoider(test_case_dict):

        try:
            for k,v in test_case_dict.items():
                final_dict[k]=eval(v) #If no exception evaluate the function and add it to final_dict

        except Exception as e:
            exception_dict[k]=e #extract exception
            test_case_dict.pop(k)
            try_except_avoider(test_case_dict) #recursive function to handle remaining functions

        finally:  #cleanup
            final_dict.update(exception_dict)
            return final_dict #combine exception dict and  final dict

    return try_except_avoider(test_case_dict) 

Run code:

def add(a,b):
    return (a+b)
def sub(a,b):
    return (a-b)
def mul(a,b):
    return (a*b)

case = {"AddFunc":"add(8,8)","SubFunc":"sub(p,5)","MulFunc":"mul(9,6)"}
solution = special_func(case)

Output looks like:

{'AddFunc': 16, 'MulFunc': 54, 'SubFunc': NameError("name 'p' is not defined")}

To convert to variables:

locals().update(solution)

Variables would look like:

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined")

'continue' is allowed within an 'except' or 'finally' only if the try block is in a loop. 'continue' will cause the next iteration of the loop to start.

So you can try put your two or more functions in a list and use loop to call your function.

Like this:

funcs = [f,g]
for func in funcs:
    try: func()
    except: continue

For full information you can go to this link


Depending on where and how often you need to do this, you could also write a function that does it for you:

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

live_dangerously(do_smth1)
live_dangerously(do_smth2)

But as other answers have noted, having a null except is generally a sign something else is wrong with your code.


While the other answers and the accepted one are correct and should be followed in real code, just for completeness and humor, you can try the fuckitpy ( https://github.com/ajalt/fuckitpy ) module.

Your code can be changed to the following:

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

Then calling myfunc() would call do_smth2() even if there is an exception in do_smth1())

Note: Please do not try it in any real code, it is blasphemy


one way you could handle this is with a generator. Instead of calling the function, yield it; then whatever is consuming the generator can send the result of calling it back into the generator, or a sentinel if the generator failed: The trampoline that accomplishes the above might look like so:

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

a generator that would be compatible with this would look like this:

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

Note that do_many_things() does not call do_smth*, it just yields them, and consume_exceptions calls them on its behalf


You could iterate through your methods...

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

I don't think you want to do this. The correct way to use a try statement in general is as precisely as possible. I think it would be better to do:

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception