[Tutor] throwing exception across modules?
Steven D'Aprano
steve at pearwood.info
Thu Sep 8 16:34:29 CEST 2011
James Hartley wrote:
> This is more a design question.
>
> One lesson C++ programmers might learn is that throwing exceptions from
> within library code is fraught with problems because the internals of
> exception handling were spelled out in the C++ standard. This manifests
Do you mean "weren't spelled out"?
> itself as problems when the library was compiled with one vendor's compiler,
> but the user of the library is using another compiler.
>
> While I understand that Python doesn't suffer from this exact problem, are
> there other reasons that raising exceptions in a module only be caught by
> consumers of the module a bad idea?
Not at all. Python is designed to use exceptions as the primary error
mechanism. Nearly every module and function you will use in Python will
use exceptions to signal errors.
A few will also use exceptions to signal non-error exceptional cases,
e.g. StopIteration is used by iterators when they run out of items.
Exceptions in Python aren't bolted on the top, they are fundamental to
the way the language works. Even things like for loops work by catching
exceptions.
> Any insight which can be shared would be most appreciated.
The only thing which sometimes catches out beginners is that they forget
to use fully-qualified names for exceptions. E.g. you may need to do this:
import socket
try:
...
except socket.error:
...
instead of just "except error".
If possible, document which exceptions your code might throw. At least,
document which exceptions you expect to throw under normal circumstances.
An exception in the top level of your module will be treated as fatal:
it will prevent the module from being imported. (When I say fatal, I
mean fatal for your module, not the caller: the caller can always catch
the exception and skip the import.)
Think carefully about what exceptions you should use. Try to integrate
with the standard Python exception hierarchy. See the docs for further
details.
It's a matter of opinion whether you should use built-in exceptions
as-is, or whether you subclass them. Subclassing can be as simple as:
class StatsError(ValueError):
pass
or as complicated as you want. But in general, keep exceptions simple.
Try not to raise private exceptions where the caller will see them. In
other words, if you define a private exception type by flagging the name
with a leading single underscore:
class _InternalUseOnly(TypeError): # single underscore means "private"
pass
then never raise it unless you also catch it.
--
Steven
More information about the Tutor
mailing list