more on exceptions

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Fri, 17 Dec 1993 17:11:01 -0500

I just came across an example of the type of global exception
processing that I *WISH* I could do in Python:

I am working on a set of classes that work differently in the
read and write ( or append ) directions. When data is being
read from disk, the class's init procedure parses the data
into fields and create instance variables for those fields.

When going in the other direction - creating a sequence of
class instances in python to be written to disk, an "empty"
instance is created ( i.e. one without any instance variables,
or maybe with a minimal set of default variables. )

If someone tries to read the non-existant instance variables
of the non initialized class, they get an AttributeError -
which may not be very meaningful to them. I would LIKE to
be able to globally catch all of the AttributeErrors and,
if they are comming from an instance of that class, change
the error to something like "Error accessing attributes of
uninitialized class instance" ( maybe you can come up with
something clearer, but you get the idea! )

Clearly, there are other ways of getting the same effect:
the proper Object-Oriented way is just NOT to allow "raw"
access to the instance variables, but to access them through
methods:

class Thing:
def name( self ):
if hasattr( self, '_name' ) : return self._name
else: raise ClassNotInititlized, '_name'

or something like that. So, YES, I'm being lazy : I don't
want to have to write a dozen instance access wrapper
methods for each class if I can avoid it. But one reason
I'm using Python *IS* that I'm lazy, and it's a lot easier
in Python than in C, C++, Perl, ... !

A generalized solution to global ( unnested ) exception processing
is probably too much to wish for, but maybe Class based exception
handling is a realistic mod: On AttributeError, check if the
class has an exception function to handle it, else: do the usual
stack unwind for an exception handler. ( Maybe one could do the
same for NameErrors on a module basis, but I don't know if there
would be a need for that, or if it could work as well. Objects
are clearly intended to be encapsulated, and giving them their
own error handler is just an extension of that encapsulation. )

class Thing:
def __except__( self, what ):
if what in legal_attrib_list :
... # this is an unexceptional exception -
# trying to use an instance var that hasn't
# been initialized.
else:
... # this is a real programming error / bug

You may raise the objection that this is misusing exceptions.
Well - I think in a sense it *is*, but it's not any more of a
"misuse" than any of the other non-exceptional exceptions we've
been discussing.

- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU>
- UVA Department of Molecular Physiology and Biological Physics