[Python-Dev] reference leaks, __del__, and annotations
Nick Coghlan
ncoghlan at gmail.com
Wed Apr 5 13:58:25 CEST 2006
Tim Peters wrote:
> Note that it's very easy to do this with __del__. The trick is for
> your type not to have a __del__ method itself, but to point to a
> simple "cleanup object" with a __del__ method. Give that "contained"
> object references to the resources you want to close, and you're done.
> Because your "real" objects don't have __del__ methods, cycles
> involving them can't inhibit gc. The cleanup object's only purpose in
> life is to close resources. Like:
>
> class _RealTypeResourceCleaner:
> def __init__(self, *resources):
> self.resources = resources
>
> def __del__(self):
> if self.resources is not None:
> for r in self.resources:
> r.close()
> self.resources = None
>
> # and typically no other methods are needed, or desirable, in
> # this helper class
>
> class RealType:
> def __init__(*args):
> ...
> # and then, e.g.,
> self.cleaner = _ResourceCleaner(resource1, resource2)
>
> ... tons of stuff, but no __del__ ....
>
> That's the simple, general way to mix cycles and __del__ without problems.
So, stealing this trick for generators would involve a "helper" object with a
close() method, a __del__ method that invoked it, and access to the
generator's frame stack (rather than to the generator itself).
class _GeneratorCleaner:
__slots__ = ["_gen_frame"]
def __init__(self, gen_frame):
self._gen_frame = gen_frame
def close(self):
# Do whatever gen.close() currently does to the
# raise GeneratorExit in the frame stack
# and catch it again
def __del__(self):
self.close()
The generator's close() method would then change to be:
def close(self):
self._cleaner.close()
Would something like that eliminate the current cycle problem?
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-Dev
mailing list