[Python-Dev] Generator cleanup idea (patch: try/finally in generators)

Matthias Urlichs smurf@noris.de
Tue, 30 Jul 2002 12:24:05 +0200


Greg:
>  I take it you usually provide a method for explicit cleanup.
>  How about giving generator-iterators one, then, called
>  maybe close() or abort(). The effect would be to raise
>  an appropriate exception at the point of the yield,
>  triggering any except or finally blocks.

Objects already have a perfectly valid cleanup method -- "__del__".

If your code is so complicated that it needs a try/yield/finally, it 
would make much more sense to convert the thing to an iterator 
object. It probably would make the code a whole lot more 
understandable, too. (It did happen with mine.)

Stated another way: functions which yield stuff are special. If that 
specialness gets buried in nested try/except/finally/whatever 
constructs, things tend to get messy. Better make that messiness 
explicit by packaging the code in an object with well-defined methods.

This is actually easy to do because of the existence of iterators, 
because this code

def some_iter(foo):
	prepare(foo)

	try:
		for i in foo:
			yield something(i)
	finally:
		cleanup(foo)

painlessly transmutes to this:

class some_iter(object):
	def __init__(foo):
		prepare(foo)

		self.foo = foo
		self.it = foo.__iter__()

	def next(self):
		i = self.it.next()
		return something(i)

	def __del__(self):
		cleanup(self.foo)

Personally I think the latter version is more readable because the 
important thing, i.e. how the next element is obtained, is clearly 
separated from the rest of the code (and one level dedented, compared 
to the first version).
-- 
Matthias Urlichs