You should use if / else to handle all cases you expect. You should not use try {} catch {} to handle everything (in most cases) because a useful Exception could be raised and you can learn about the presence of a bug from it.
Order of exceptions If you have multiple catch blocks for a single try and if the exceptions classes of them belong to the same hierarchy, You need to make sure that the catch block that catches the exception class of higher-level is at last at the last in the order of catch blocks.
You generally throws an exception when you want to notify the caller of the method of some failures. Show activity on this post. As others have said, as a general rule, you should catch an exception when you can actually handle it, otherwise, just throw it.
In 'try-catch' the codes to handle the exceptions and what exception to be handled, that are easily readable. In 'if-else', we have one else block corresponding to one if block. Or we need to define another condition with command 'else if'. In 'try-catch' we don't have to define each 'try' block with a 'catch' block.
You should prefer try/except
over if/else
if that results in
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
In this particular case, you should use something else entirely:
x = myDict.get("ABC", "NO_ABC")
In general, though: If you expect the test to fail frequently, use if
. If the test is expensive relative to just trying the operation and catching the exception if it fails, use try
. If neither one of these conditions applies, go with whatever reads easier.
Using try
and except
directly rather than inside an if
guard should always be done if there is any possibility of a race condition. For example, if you want to ensure that a directory exists, do not do this:
import os, sys
if not os.path.isdir('foo'):
try:
os.mkdir('foo')
except OSError, e
print e
sys.exit(1)
If another thread or process creates the directory between isdir
and mkdir
, you'll exit. Instead, do this:
import os, sys, errno
try:
os.mkdir('foo')
except OSError, e
if e.errno != errno.EEXIST:
print e
sys.exit(1)
That will only exit if the 'foo' directory can't be created.
If it's trivial to check whether something will fail before you do it, you should probably favor that. After all, constructing exceptions (including their associated tracebacks) takes time.
Exceptions should be used for:
break
doesn't get you far enough), or...Note that oftentimes, the real answer is "neither" - for instance, in your first example, what you really should do is just use .get()
to provide a default:
x = myDict.get('ABC', 'NO_ABC')
As the other posts mention, it depends on the situation. There are a few dangers with using try/except in place of checking the validity of your data in advance, especially when using it on bigger projects.
e.g., suppose you had:
try:
x = my_list[index_list[3]]
except IndexError:
x = 'NO_ABC'
The IndexError says nothing about whether it occurred when trying to get an element of index_list or my_list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With