Since try-finally can't be used in a generator, it can be somewhat tricky to ensure that a resource is released if the generator is exited early. This solution wraps the generator with an enclosing class to ensure the resource is released.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | Python 2.2.1 (#34, Apr  9 2002, 19:34:33) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from __future__ import generators
>>> def g():
...     for i in range(5):
...             yield i
...
>>> for x in g():
...     print x
...
0
1
2
3
4
>>> def acquireResource():
...     print 'Resource Acquired'
...
>>> def releaseResource():
...     print 'Resource Released'
...
>>> class GeneratorWrapper:
...     def __init__(self, generator):
...             self.generator = generator
...             acquireResource()
...     def __del__(self):
...             releaseResource()
...     def __iter__(self):
...             return self
...     def next(self):
...             return self.generator.next()
...
>>> def testNormalUse():
...     w = GeneratorWrapper(g())
...     for x in w:
...             print x
...
>>> testNormalUse()
Resource Acquired
0
1
2
3
4
Resource Released
>>> def testAbortedUse():
...     w = GeneratorWrapper(g())
...     for x in w:
...             print x
...             if x > 2:
...                     return
...
>>> testAbortedUse()
Resource Acquired
0
1
2
3
Resource Released
>>>
 | 
Solution due to GvR; I wrote it up here as an example. But don't let that disuade you from correcting my errors!

 Download
Download Copy to clipboard
Copy to clipboard