[Python-3000] Removing __del__
greg.ewing at canterbury.ac.nz
Wed Sep 27 02:36:35 CEST 2006
Giovanni Bajo wrote:
> Is that easier or harder to detect such a cycle, compared to accidentally
> adding a reference to self (through implicit nested scopes, or bound
> methods) in the finalizer callback?
I would put a notice in the docs strongly recommending that
only global functions be registered as finalizers, not
nested functions or bound methods.
While not strictly necessary (or sufficient) for safety,
following this guideline would greatly reduce the chance
of accidentally creating troublesome cycles, I think.
And if you did accidentally create such a cycle, it seems
to me it would be much easier to fix than if you were
using __del__, since you only need to make an adjustment
to the parameter list of the finalizer.
With __del__, you need to refactor your whole finalization
strategy and create another object to do the finalization,
which is a much bigger upheaval.
> Most finalization APIs (including yours) create
> cycles just by using them, which also mean that you *must* wait for the GC
> to kick in before the object is finalized
No, a weakref-based finalizer will kick in just as soon
as __del__ would. I don't know what makes you think
> will absolutely not solve the problem per-se: the user will
> still have to pay attention and understand the hoops
Certainly, but it will make it much more obvious
that the hoops are there in the first place, and
exactly where and what shape they are.
> So, why do we not spend this same time trying to
> *fix* __del__ instead?
So far nobody has found a *way* to fix __del__
(really fix it, that is, not just paper over the
cracks). And a lot of smart people have given it
a lot of thought over the years.
If someone comes up with a way some day, we can
always put __del__ back in. But I don't feel like
holding my breath waiting for that to happen, when
we have something else that we know will work.
>> # Use closure to get at weakref to allow direct invocation
>> # This creates a cycle, so this approach relies on cyclic GC
>> # to clean up the finalizer objects!
This implementation is broken. There's no need
to create any such cycle.
More information about the Python-3000