3

Is there any way to deal with exceptions within if statements, other than putting a try, except bracket around the whole lot, or to test for the exception on each line in advance?

For example, say i had the simplified code:

 if a[0] == "a":
     return("foo")
 elif a[1] == "b":
     return("bar")
 elif a[5] == "d":
     return("bar2")
 elif a[2] == "c":
     return("bar3")
 else:
     return("baz") 

If a was word_of_six_characters_or_more this would work fine. If it is a shorter word it raises an exception on the line elif a[5] == "d". Obviously it is possible to test for exceptions in advance (e.g. changing elif a[5] == "d" to elif len(a) >5 and a[5] =="d", which then relies on the first part being False and thus the second never executed). My question is, is there any other way of just causing exceptions to be treated as False and to proceed to the next elif statement rather than throwing up the exception - or similarly, to include try except clauses within a elif line?

(obviously, it is possible that there is no way, and thus getting confirmation that adding in pre-tests for exceptions is how to proceed would be good to know).

(I should probably note, that my code is quite substantially more complicated than the above, and while i could put in pre-checks, there would be quite a lot of them, so just trying to see if there is a simpler solution.)

kyrenia
  • 5,431
  • 9
  • 63
  • 93
  • There is no way to treat exceptions as `False`. – thebjorn Jan 16 '16 at 01:27
  • Possible duplicate of [Why list doesn't have safe "get" method like dictionary?](http://stackoverflow.com/questions/5125619/why-list-doesnt-have-safe-get-method-like-dictionary) – styvane Jan 16 '16 at 01:34
  • 1
    @user3100115 I think that question (as well of course the answers here) certainly helped - that said, i'm not sure that this question is a duplicate, since i think the two question are asking quite different things. – kyrenia Jan 16 '16 at 01:50

2 Answers2

5

Well, there are 2 ways you could easily handle this. You could slice a single character which will be empty if it doesn't exist. E.g.,

if a[0:1] == "a":
    return("foo")
elif a[1:2] == "b":
    return("bar")
elif a[5:6] == "d":
    return("bar2")
elif a[2:3] == "c":
    return("bar3")
else:
    return("baz") 

Or, you could write a wrapper function to ignore the IndexErrors. E.g.,

def get(obj, index):
    try:
        return obj[index]
    except IndexError:
        return

if get(a, 0) == "a":
    return("foo")
elif get(a, 1) == "b":
    return("bar")
elif get(a, 5) == "d":
    return("bar2")
elif get(a, 2) == "c":
    return("bar3")
else:
    return("baz") 
Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
0

There isn't a way to treat any raised exception as False. You could put in a bunch of pre-checks to guard against the exceptions (like you mentioned), or write a function that catches the exception and returns False (like @cpburnz mentioned).

Depending on the complexity you may be better off to define rules which you can iterate through in order, the first rule to match is then used to determine the action.

For example:

def checkA(val):
    try:
        # check val
        return ...
    except Exception:
       return False

def doA(val):
    # act on the value
    return ...

conditions = (
    { 'check': checkA, 'action': doA },
    { 'check': checkB, 'action': doB },
    ...
)

for con in conditions:
    if con['check'](a):
        return con['action'](a)
John Keyes
  • 5,479
  • 1
  • 29
  • 48