This question already has an answer here:
- Using try vs if in python 9 answers
When is exception handling more preferable than condition checking? There are many situations where I can choose using one or the other.
For example, this is a summing function which uses a custom exception:
# module mylibrary
class WrongSummand(Exception):
pass
def sum_(a, b):
""" returns the sum of two summands of the same type """
if type(a) != type(b):
raise WrongSummand("given arguments are not of the same type")
return a + b
# module application using mylibrary
from mylibrary import sum_, WrongSummand
try:
print sum_("A", 5)
except WrongSummand:
print "wrong arguments"
And this is the same function, which avoids using exceptions
# module mylibrary
def sum_(a, b):
""" returns the sum of two summands if they are both of the same type """
if type(a) == type(b):
return a + b
# module application using mylibrary
from mylibrary import sum_
c = sum_("A", 5)
if c is not None:
print c
else:
print "wrong arguments"
I think that using conditions is always more readable and manageable. Or am I wrong? What are the proper cases for defining APIs which raise exceptions and why?
If you're asking, you should probably be using exceptions. Exceptions are used to indicate exceptional circumstances, a specific case where things work differently from other cases. This is the case for prettymuch all errors and for many other things as well.
In your second implementation of
sum_
, the user has to check every single time what the value was. This is reminiscent of the C/Fortran/other-languages boilerplate (and frequent source of errors) where error codes go unchecked that we avoid. You have to write code like this at all levels to be able to propagate errors. It gets messy and is especially avoided in Python.A couple other notes:
ValueError
andTypeError
are appropriate.Exception
. The built-in exception hierarchy is here.I would never implement a function like
sum_
, since typechecking makes your code less flexible, maintainable, and idiomatic.I would simply write the function
which would work if the objects were compatible and if not it would already throw an exception, the
TypeError
that everyone is used to seeing. Consider how my implementation worksMy code was shorter and simpler yet is more robust and flexible than yours. This is why we avoid typechecking in Python.