Exceptions¶
Exceptions can be a powerful tool for you and for code development and usage, but can also be a drawback (they can have a huge impact on performance) when not being used properly.
Probably you are using exceptions
even without noticing.
For example, for lists raise a
StopIteration exception
when you iterate over them (e.g. in a for loop)
and there are no more items left.
You should be aware when to use and when not use exceptions. Do not use exceptions for flow-control. Exceptions exist for exceptional situations: events that are not a part of normal execution.
No:
def is_multiple(x, y):
if x % y == 0:
return True
else:
raise Exception()
Yes:
def is_multiple(x, y):
if y == 0:
raise Exception()
if x % y == 0:
return True
else:
return False
If your code is going to capture exceptions that you would like to manage or to set a particular message to help users or developers what went wrong and where, a good practice is to define your own exception class.
User exceptions should typically derive from, at least,
Exception:
class MyPackageError(Exception):
pass
Most exceptions are defined with names that end in “Error”.
If you want to create a set of exceptions you can create a base class and derive from that:
class MyPackageError(Exception):
pass
class UserInputError(MyPackage):
pass
class ClusterError(MyPackage):
pass
It is also useful to give a meaningful error message to your exceptions:
In [1]: class MyPackage(Exception):
...: pass
...:
In [2]: raise MyPackage('Exception raised')
---------------------------------------------------------------------------
MyPackage Traceback (most recent call last)
<ipython-input-2-e2bcd5645bf9> in <module>
----> 1 raise MyPackage('Exception raised')
MyPackage: Exception raised
No:
def f():
if something_goes_wrong:
raise Exception()
Yes:
def f():
if something_goes_wrong:
raise Exception('This has occurred')
Handling exceptions¶
In Python exceptions are handled with the try-except clause.
Avoid try-except whenever is possible
Limit the try clause to the minimum possible lines
Indicate the exception you want to capture
No:
def to_int(v):
try:
return int(v)
except:
None
Yes:
def to_int(v):
try:
v = int(v)
except ValueError:
return None
else:
return v