[Python-3000] PEP: Eliminate __del__
Phillip J. Eby
pje at telecommunity.com
Tue May 1 18:09:30 CEST 2007
At 12:31 AM 5/1/2007 -0700, Raymond Hettinger wrote:
>The alternative is to code the automatic finalization steps using
>weakref callbacks. For those used to using __del__, it takes a little
>while to learn the idiom but essentially the technique is hold a proxy
>or ref with a callback to a boundmethod for finalization:
> self.resource = resource = CreateResource()
> self.callbacks.append(proxy(resource, resource.closedown))
>In this manner, all of the object's resources can be freed automatically
>when the object is collected. Note, that the callbacks only bind
>the resource object and not client object, so the client object
>can already have been collected and the teardown code can be run
>without risk of resurrecting the client (with a possibly invalid state).
I'm a bit confused about the above. My understanding is that in order for
a weakref's callback to be invoked, the weakref itself *must still be
live*. That means that if 'self' in your example above is collected, then
the weakref no longer exists, so the closedown won't be called.
Yet, at the same time, it appears that in your example, deleting
self.resource would *not* cause resource to be GC'd either, because the
weakref still holds a reference to 'resource.closedown', which in turn must
hold a reference to 'resource'.
So, at first glance, your example looks like it can't possibly do the right
thing, ever, unless I'm missing something rather big. In which case, the
explanation for *how* this is supposed to work should go in the PEP.
In principle I'm in favor of ditching __del__, as long as there's actually
a viable technique for doing so. My own experience has been that setting
up a simple mechanism to replace it (and that actually works) is really
difficult, because you have to find some place for the weakref itself to
live, which usually means a global dictionary or something of that
sort. It would be nice if the gc or weakref modules grew a facility to
make it easier to register finalization callbacks, and could optionally
check whether you were registering a callback that referenced the thing you
were tying the callback's life to.
More information about the Python-3000