[Python-3000] PEP: Eliminate __del__
Giovanni Bajo
rasky at develer.com
Thu May 3 09:25:44 CEST 2007
On 01/05/2007 18.09, Phillip J. Eby 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.
Yes, but as far as I understand it, the GC does special care to ensure that
the callback of a weakref that is *not* part of a cyclic trash being collected
is always called. See this comment in gcmodule.c:
* OTOH, if wr isn't part of CT, we should invoke the callback: the
* weakref outlived the trash. Note that since wr isn't CT in this
* case, its callback can't be CT either -- wr acted as an external
* root to this generation, and therefore its callback did too. So
* nothing in CT is reachable from the callback either, so it's hard
* to imagine how calling it later could create a problem for us. wr
* is moved to wrcb_to_call in this case.
I might be wrong about the inners of GC, but I have used the weakref idiom
many times and it always appeared to be working.
> 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.
Others suggested that such a framework could be prepared, but I have not seen
one yet.
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.
That'd be absolutely great! OTOH, the GC could possibly re-verify such
assertion every time it kicks in (when a special debug flag is activated).
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
More information about the Python-3000
mailing list