Re: does python have useless destructors?

From: Duncan Booth (me_at_privacy.net)
Date: 06/12/04


Date: 12 Jun 2004 13:34:11 GMT


"Roger Binns" <rogerb@rogerbinns.com> wrote in
news:q3ipp1-4bp.ln1@home.rogerbinns.com:

> Duncan Booth wrote:
>> The object itself can know that it needs to be safely disposed of,
>> but it cannot tell *when* to dispose of itself. My example function
>> might create multiple objects some of which need disposing when the
>> function returns, and others have a longer lifetime. The choice
>> between disposing at the end of the function or when some containing
>> object is disposed has to be one for the caller.
>
> You have totally confused me now. Ignoring special cases such as
> cycles, Python destructs an object when there are no references left
> to it, and in CPython that happens at the moment the last reference is
> released. So in normal code the objects will go away as names
> referencing them go out of scope.

I wouldn't say that cycles are special cases exactly.

C Python destroys an object when no references are left. Jython and
IronPython destroy objects when the underlying garbage collector feels like
it (i.e. when the object is no longer reachable, which even without cycles
is not the same as having no references). In most, if not all of these
cases the underlying garbage collector is generational, so you can't even
be sure that unreachable objects will be destroyed by the next collection,
it may take several collections. Python (as a language) is careful not to
specify a specific implementation (such as reference counting) because that
would prevent efficient implementation on a variety of platforms.

>
> If the Python object is a proxy for another non-Python visible object
> (such as a C level filehandle or GUI Window). In those cases
> the extension module author has to deal with the situation, either by
> adding an extra reference (the C level object is then the remaining
> reference) or handling the lifetime of the C level object
> independently.
>
> But for this thread, the actual problem is that __del__ methods may
> not be called on objects, and if you read the doc implies they almost
> never will be called. So we have the counter-intuitive (and IMHO user
> hostile) situation where someone marks a class as needing extra code
> to run to destroy it, and Python addresses that by saying you will
> be lucky if the object will be destroyed (ie by not destroying the
> object).

No, Python guarantees that the object will (almost always) be destroyed. It
just doesn't make guarantees about when that will happen. If you want
guarantees about resources being released you have to write the code to do
that yourself (e.g. with try..finally). The same applies for other
languages such as Java, or languages running in Microsoft's .Net framework.

Guaranteeing that all resources will be released at a specific time has
implications for performance, and finalisers are actually pretty rare in
practice, so the usual solution is to compromise.