[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

AltStyle によって変換されたページ (->オリジナル) /