Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's an elegant way to catch the same exception multiple times?

Tags:

python

I have some Python code that tries a bunch of different database queries before it concludes that the database is empty and gives up. Here is a simplified example:

try:
    result = Object.get(name="requested_object")
except Object.DoesNotExist:
    try:
        result = Object.get(name="default_object")
    except Object.DoesNotExist:
        try:
            result = Object.get(pk=1)
        except Object.DoesNotExist:
            print "The database is empty!"
            raise

Note that the exception I'm trying to catch is the same every time. Surely there must be a way to do this without needless repetition and nesting. How can I achieve the same behavior without the nested try...except statements?

like image 210
Jaap Joris Vens Avatar asked Oct 09 '14 11:10

Jaap Joris Vens


2 Answers

for args in [{'name':"requested_object"}, {'name':"default_object"}, {'pk':1}]:
    try:
        result = Object.get(**args)
    except Object.DoesNotExist as e:
        continue
    else:
        break
else:
    raise e

It's not clear what exception you want to raise if you never find what you want, you might have to adjust that part. Also, the scoping of exception values has changed in Python 3, so e won't be available to raise.

like image 192
Ned Batchelder Avatar answered Oct 05 '22 18:10

Ned Batchelder


Nested and complicated control blocks are easier to read when wrapped into a function:

def result():
    try:
        return Object.get(name="requested_object")
    except Object.DoesNotExist:
        pass

    try:
        return Object.get(name="default_object")
    except Object.DoesNotExist:
        pass

    return Object.get(pk=1) # NB: no "try" here. If it's going to fail, let it fail

This way you avoid excessive indentation and "mental jumps" like break/continue.

like image 45
georg Avatar answered Oct 05 '22 17:10

georg