How to write multiple try statements in one block in python?

Question:

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

Asked By: alwbtc

||

Answers:

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.

Answered By: alexvassel

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.

Answered By: Fredrik Håård

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 
Answered By: gaqzi

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'
Answered By: Kenan Banks

Here is the simplest way I found, just embed the try under the previous except.

try:
    do()
except:
    try:
        do2()
    except:
        do3()
Answered By: sparrow
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
Answered By: Raghu nathan

if you want multiple try statments you can do it like this, including the except statement. Extract (refactor) your statements. And use the magic of and and or to decide when to short-circuit.

python
def a():
try: # a code
except: pass # or raise
else: return True

def b():
    try: # b code
    except: pass # or raise
    else: return True

def c():
    try: # c code
    except: pass # or raise
    else: return True

def d():
    try: # d code
    except: pass # or raise
    else: return True

def main():   
    try:
        a() and b() or c() or d()
    except:
        pass
Answered By: Engr Ali