Using 'Try' VS. 'If' in Python

Using 'try' vs. 'if' in Python

You often hear that Python encourages EAFP style ("it's easier to ask for forgiveness than permission") over LBYL style ("look before you leap"). To me, it's a matter of efficiency and readability.

In your example (say that instead of returning a list or an empty string, the function were to return a list or None), if you expect that 99 % of the time result will actually contain something iterable, I'd use the try/except approach. It will be faster if exceptions really are exceptional. If result is None more than 50 % of the time, then using if is probably better.

To support this with a few measurements:

>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175

So, whereas an if statement always costs you, it's nearly free to set up a try/except block. But when an Exception actually occurs, the cost is much higher.

Moral:

  • It's perfectly OK (and "pythonic") to use try/except for flow control,
  • but it makes sense most when Exceptions are actually exceptional.

From the Python docs:

EAFP

Easier to ask for forgiveness than
permission. This common Python coding
style assumes the existence of valid
keys or attributes and catches
exceptions if the assumption proves
false. This clean and fast style is
characterized by the presence of many
try and except statements. The
technique contrasts with the LBYL
style common to many other languages
such as C.

Difference between try and if

I believe you're asking about the paradigm "Easier to ask for forgiveness than for permission" which is sometimes quoted as a Python guideline.

In this context try / except corresponds to trying and asking for forgiveness, while if corresponds to asking for permission then trying.

Have a look: http://docs.python.org/glossary.html#term-eafp

When do we need to use try, except in python? Is it similar to if, else ?

The try and except blocks are used to catch and handle exceptions. The program will first run the try statement "normally". If there are any exceptions that trigger in the try statement, the except statement will trigger. For example,

try:
print(str) #Here, str isn't defined and you will get an exception which triggers the except statement
except NameError: #Here, you specify which exception you think might happen
#Do something

You can have as many exception blocks as you want! Also note that if you catch an exception the other ones will not trigger. Also note that an exception block with no arguments will catch all exceptions.

The finally block can be added on and triggers even if there was an exception or not. This can be helpful for closing and cleaning objects. Another example,

try:
#stuff
except:
#stuff if exception
finally:
#do stuff even if there is or is not an exception

I should also mention the pass function. You should use it if you want to ignore exceptions. Example,

try:
#stuff
except:
pass #i don't want to do anything

Hope I helped!

Better to 'try' something and catch the exception or test if it's possible first to avoid an exception?

You should prefer try/except over if/else if that results in

  • speed-ups (for example by preventing extra lookups)
  • cleaner code (fewer lines/easier to read)

Often, these go hand-in-hand.


speed-ups

In the case of trying to find an element in a long list by:

try:
x = my_list[index]
except IndexError:
x = 'NO_ABC'

the try, except is the best option when the index is probably in the list and the IndexError is usually not raised. This way you avoid the need for an extra lookup by if index < len(my_list).

Python encourages the use of exceptions, which you handle is a phrase from Dive Into Python. Your example not only handles the exception (gracefully), rather than letting it silently pass, also the exception occurs only in the exceptional case of index not being found (hence the word exception!).


cleaner code

The official Python Documentation mentions EAFP: Easier to ask for forgiveness than permission and Rob Knight notes that catching errors rather than avoiding them, can result in cleaner, easier to read code. His example says it like this:

Worse (LBYL 'look before you leap'):

#check whether int conversion will raise an error
if not isinstance(s, str) or not s.isdigit():
return None
elif len(s) > 10: #too many digits for int conversion
return None
else:
return int(s)

Better (EAFP: Easier to ask for forgiveness than permission):

try:
return int(s)
except (TypeError, ValueError, OverflowError): #int conversion failed
return None

Why `try ... except` is faster than `if`?

The additional runtime comes from the .keys() call. If you want to prevent that extra call and still stay with if and else, try something like this:

obj = d.get(key)
if obj:
obj.append(element)
else:
d[key] = [element]

Alternatively you can use a defaultdict which does this in the background. Example:

from collections import defaultdict
d = defaultdict(list)
d['123'].append('abc')

can i combine if else and with try catch python?

You can raise an exception if the function returns False, by doing:

s = '127.0.0.0'

def validate(a):
a = a.split('.')
if len(a) !=4:
return False
for x in a :
if not x.isdigit():
return False
i = int(x)
if i < 0 or i > 255 :
return False
return True

try:
if not validate(s): #ip validation
raise TypeError
except TypeError:
print("insert you're ip correctly")

Note: you probably want to return True for the end, since I believe that's when the function validates successfully, and a = a.split('.') not s.split, or else you're splitting the global variable s.

Tip: when using try...except, try to catch a specific error than to use the catch-all except:.

Python: try-except vs if-else to check dict keys

Exception handling is generally much slower than an if statement. With the presence of nested dictionaries, it is easy to see why the author used an exception statement. However, the following would work also.

var = mydict.get(a,{}).get(b,None)

if var is None:
print("Not found")
else:
print("Found: " + str(var))

The use of get on the dict object returns a default value when the key is not present.

Python if vs try-except

You're setting alist only once. The first call to "tryway" clears it, then every successive call does nothing.

def tryway():
alist = range(1000)
try:
while True:
alist.pop()
except IndexError:
pass

def ifway():
alist = range(1000)
while True:
if alist == []:
break
else:
alist.pop()
if __name__=='__main__':
from timeit import Timer
print "Testing Try"
tr = Timer("tryway()","from __main__ import tryway")
print tr.timeit(10000)
print "Testing If"
ir = Timer("ifway()","from __main__ import ifway")
print ir.timeit(10000)

>>> Testing Try
>>> 2.09539294243
>>> Testing If
>>> 2.84440898895


Related Topics



Leave a reply



Submit