Use apply() or not, and raising multiple exceptions (co-routines?)

Roy Smith roy at panix.com
Sun Mar 10 12:18:39 EST 2002


I've got some code which performs a series of integrety checks against a 
data set.  The way I've set things up, I put each check in its own method 
and keep a list of all the methods:

checks = []

def check1 (self, data):
   do stuff
checks.append (check1)

def check2 (self, data):
   do other stuff
checks.append (check2)

and so on.  This makes it easy to add and delete bits of policy over time.  
I cycle over the checking functions by doing:

for check in self.checks:
    check (self, data)

I could have also written this as:

for check in self.checks:
    apply (check, [data])

is there any particular reason to prefer one style over the other?  Having 
walked a few people through the code, I'm starting to think that the latter 
is a little more self-explanitory (especially for junior pythonistas).  On 
the other hand, I suspect it's slighly less efficient.

A related question is how best to have the check methods do more than one 
thing.  Right now, I just have each method print an error message when it 
finds a problem.  A given method might check for more than one related 
problem.  I'd like to pull the printing out of the functions themselves, 
and go to an exception based system, where I'd do something like:

for check in self.checks:
   try:
      check (self, data)
   except IntegrityCheckError, message:
      print 'failed check:', message

The problem is I'd only catch the first problem found by a given check 
method.  The way around that would be to make the check methods each look 
for one, and only one, problem, but that wouldn't be inefficient 
(especially since some methods would share a lot of code and repeat a lot 
of work).  Is there some way to stack exceptions, so a given method can 
raise two or more of them in sequence, or something having the same effect?

The only thing I can see is to have each check method return a list of 
problems it found.  Then, the main loop would look like:

for check in self.checks:
   for problem in check (self, data):
      print 'failed check:', problem

but that implies pushing a lot of scaffolding down into the check methods, 
making them build and manipulate error lists to return.  I'm trying to keep 
them as clean as possible, so they're easy to write and debug.
   
It would be kind of neat if after doing the except clause, my method picked 
up again at the statement after the raise.  I guess what I'd have then is 
the caller and callee acting as co-routines.  Is there a way to do anything 
like that?



More information about the Python-list mailing list