try..yield..finally problem: a proposed solution.
Alan Kennedy
alanmk at hotmail.com
Fri Jun 6 07:08:46 EDT 2003
Michael Sparks wrote:
> Taking your suggestion, you get a cleaned up version which is
> pretty elegant:
>
> def finfunc():
> try:
> try:
> # Risky code, e.g.
> for i in xrange(10):
> t=i/random.randint(0,10)
> yield "data",i
> raise Finality
> except:
> print "Finally"
> raise
> except Finality:
> pass
>
> for v in finfunc():
> print v
[ Stuff elided ]
> But you [sometimes] get a 'exceptions must not be of 'NoneType' error.
Indeed, I discovered this during my prototyping, which is why I had the
structure that I did.
> If you use the original (form 3 for convenience):
> # Form 3
> try:
> yield
> except Exception,x:
> yield
> raise x
But this isn't the original form, since there is no "finally" processing in it,
i.e. the second yield is only reached if there is an exception...
Adding in "finally" processing, this form is
try:
yield
raise Finality
except Exception, x:
yield
raise x
which does not clear or in any way "lose" the exception in the following code,
under Python 2.3a2.
#------------------------------------------------------------------
import random
class Finality(Exception): pass
def finfunc():
try:
try:
# Risky code, e.g.
for i in range(10):
x = 1/int(random.random()*10)
yield x
print "Successful processing"
raise Finality
except Exception, x:
print "Finally"
yield 42
raise x
except Finality:
print "Finality discarded"
except Exception, x:
print "Told you that code was risky, didn't I?: %s" % str(x)
for v in finfunc():
print v
#------------------------------------------------------------------
Incidentally, if you want to see the "exceptions cannot be Nonetype" exception
that Michael describes, then change the above definition of finfunc to remove
the explicit declaration of Exception, x: like so
def finfunc():
try:
try:
# Risky code, e.g.
for i in range(10):
x = 1/int(random.random()*10)
yield x
print "Successful processing"
raise Finality
except: # <- this is different
print "Finally"
yield 42
raise # <- and so is this
except Finality:
print "Finality discarded"
except Exception, x:
print "Told you that code was risky, didn't I?: %s" % str(x)
regards,
--
alan kennedy
-----------------------------------------------------
check http headers here: http://xhaus.com/headers
email alan: http://xhaus.com/mailto/alan
More information about the Python-list
mailing list