Destruction of generator objects
Stefan Bellon
sbellon at sbellon.de
Sat Aug 11 08:00:17 EDT 2007
On Sat, 11 Aug, Kay Schluehr wrote:
> Honestly, I'd recommend wrapping the generator into a function object,
> create the resource on construction ( or pass it ) and destroy it
> implementing __del__.
>
> def gen_value(self):
> while True:
> yield self.iter.next()
>
> class GeneratorObj(object):
> def __init__(self, obj, gen):
> self.iter = make_iter(obj)
> self.gen = gen(self)
>
> def __del__(self):
> destroy(self.iter)
>
> def next(self):
> return self.gen.next()
Ok, I think there is an __iter__ missing in order to implement the
iterator protocol, and I don't see why the generator cannot be inside
the class itself.
Anyway, I came up with this code now:
class ListGenerator(object):
def __init__(self, iter):
print "gen init"
self.iter = iter
self.gen = self._value()
def __del__(self):
print "gen del"
destroy(self.iter)
def _value(self):
print "gen value"
while more(self.iter):
yield next(self.iter)
def __iter__(self):
print "gen iter"
return self
def next(self):
print "gen next"
return self.gen.next()
When iterating over such a generator, I see the following output:
>>> list(obj)
gen init
gen iter
gen next
gen value
gen next
gen next
gen next
gen next
['Item1', 'Item2', 'Item3', 'Item4']
But I do not see an output of "gen del" which makes me think that the
destructor is not called, thus not releasing the resource. It seems I
have not completely understood how generators work ...
--
Stefan Bellon
More information about the Python-list
mailing list