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!