alwbtc
alwbtc

Reputation: 29445

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

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

Upvotes: 18

Views: 40199

Answers (7)

Engr Ali
Engr Ali

Reputation: 359

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.

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

Upvotes: 0

Raghu nathan
Raghu nathan

Reputation: 1

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

Upvotes: -2

sparrow
sparrow

Reputation: 11460

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

try:
    do()
except:
    try:
        do2()
    except:
        do3()

Upvotes: 4

Kenan Banks
Kenan Banks

Reputation: 211980

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'

Upvotes: 15

Fredrik Håård
Fredrik Håård

Reputation: 2915

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.

Upvotes: 28

gaqzi
gaqzi

Reputation: 3797

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 

Upvotes: 5

alexvassel
alexvassel

Reputation: 10740

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.

Upvotes: 1

Related Questions