exception handling in complex Python programs
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Thu Aug 21 06:22:46 EDT 2008
On Thu, 21 Aug 2008 00:34:21 -0700, eliben wrote:
> On Aug 19, 7:19 pm, eliben <eli... at gmail.com> wrote:
>> Python provides a quite good and feature-complete exception handling
> <snip>
>
> Thanks for the interesting discussion. Armed by the new information and
> few online sources, I blogged a summary for myself on the topic of
> robust exception handling in Python:
>
> http://eli.thegreenplace.net/2008/08/21/robust-exception-handling/
Just a few random points. You say:
"Exceptions are better than returning error status codes. Some languages
(like Python) leave you with no choice as the whole language core and
standard libraries throw exceptions."
Of course you have a choice. Your function can return anything you want:
def mysqrt(x):
try:
return math.sqrt(x)
except ValueError:
return "Code 37"
I've written functions that return an object on success and None if the
function failed. In the context of what I was doing, that made more sense
than raising an exception.
Furthermore, the str.find() method returns -1 for not found instead of
raising an exception. There are probably other examples as well.
You also wrote:
"Exceptions exist for exceptional situations: unanticipated events that
are not a part of normal execution."
Exceptions can and often are anticipated. E.g. if you write code that
opens a URL, you better anticipate that the server might reject your
connection. You better expect to be asked for a cookie, or
authentication. If you check for robots.txt, you better expect that it
might not exist. That's all normal execution.
"When a programmer calls str.find('substring') he doesn’t expect an
exception to be thrown if the substring isn’t found."
But if he called str.index() then he does expect an exception to be
thrown, just like for list.index() and dict[key] can raise exceptions.
They are neither bugs nor unexpected.
"This is what he called find for. A better approach is to return a
special value like None or -1."
Sometimes, maybe. But usually not, because that just complicates the
calling code. You end up writing code that repeatedly checks that the
result isn't a special value before doing anything.
Often a better tactic is to write your code assuming that the result is
the unexceptional case, and then wrap it in a try...except block to catch
the exceptional cases.
"When used for flow-control, exceptions are like goto. There might be a
few esoteric cases in which they’re appropriate, but 99.99% of the time
they are not."
I strongly disagree. try...except is like break or continue. Yes, it
breaks the linear flow of control, but not in a wild, dangerous way like
goto.
It is possible to write bad code with exceptions, but you can write bad
code with anything.
--
Steven
More information about the Python-list
mailing list