Destruction of generator objects

Marc 'BlackJack' Rintsch bj_666 at gmx.net
Sat Aug 11 15:05:50 CEST 2007


On Sat, 11 Aug 2007 14:50:33 +0200, Stefan Bellon wrote:

> On Sat, 11 Aug, Kay Schluehr wrote:
> 
>> But why shall the destructor be called? Your example does not indicate
>> that a ListGenerator object is somewhere destroyed neither explicitely
>> using del nor implicitely by destroying the scope it is living in.
> 
> After having constructed the list itself, the generator is exhausted
> and not iterated or referenced anymore, so the generator should be
> destroyed, shouldn't it?
> 
> Ok, let's make the example easier and take out the external iterator
> resource and just concentrate on the Python part:
> 
> class ListGenerator(object):
>     def __init__(self):
>         print "gen init"
>         self.gen = self._value()
> 
>     def __del__(self):
>         print "gen del"
> 
>     def _value(self):
>         print "gen value"
>         for i in xrange(4):
>             yield i
> 
>     def __iter__(self):
>         print "gen iter"
>         return self
> 
>     def next(self):
>         print "gen next"
>         return self.gen.next()
> 
> Now, doing the following:
> 
>>>> a = ListGenerator()
> gen init
>>>> a
> <__main__.ListGenerator object at 0x4020c3ec>
>>>> for i in a: print i
> ... 
> gen iter
> gen next
> gen value
> 0
> gen next
> 1
> gen next
> 2
> gen next
> 3
> gen next
>>>> del a
>>>>
> 
> So why is the destructor not called when the generator is even
> explicitly 'del'ed?

The generator is not ``del``\ed, just the name `a` is removed.

> Does somebody else still hold a reference on it?

Yes, the interactive Python shell holds the last non-`None` result in `_`:

>>> from forum import ListGenerator
>>> a = ListGenerator()
gen init
>>> a
<forum.ListGenerator object at 0xb7d12c4c>
>>> for i in a: print i
...
gen iter
gen next
gen value
0
gen next
1
gen next
2
gen next
3
gen next
>>> del a
>>> _
<forum.ListGenerator object at 0xb7d12c4c>
>>> 42
gen del
42

> But then, even when terminating the interpreter, __del__ is not called.

Because that is not guaranteed by the language reference.  The reason why
it is a bad idea to depend on `__del__` for important resource management.

Ciao,
	Marc 'BlackJack' Rintsch



More information about the Python-list mailing list