Destruction of generator objects

Stefan Bellon sbellon at sbellon.de
Sat Aug 11 14:00:17 CEST 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