[Python-Dev] finalization again
Guido van Rossum
Tue, 07 Mar 2000 12:33:31 -0500
[Tim tells Guido again that he finds the Java rules bad, slinging some
mud at Guy Steel, but without explaining what the problem with them
is, and then asks:]
> 1. I don't know why JPython doesn't execute __del__ methods at all now, but
> have to suspect that the Java rules imply an implementation so grossly
> inefficient in the presence of __del__ that Barry simply doesn't want to
> endure the speed complaints. The Java spec itself urges implementations to
> special-case the snot out of classes that don't override the default
> do-nothing finalizer, for "go fast" reasons too.
Something like that, yes, although it was Jim Hugunin. I have a
feeling it has to do with the dynamic of __del__ -- this would imply
that *all* Python class instances would appear to Java to have a
finalizer -- just in most cases it would do a failing lookup of
__del__ and bail out quickly. Maybe some source code or class
analysis looking for a __del__ could fix this, at the cost of not
allowing one to patch __del__ into an existing class after instances
have already been created. I don't find that breach of dynamicism a
big deal -- e.g. CPython keeps copies of __getattr__, __setattr__ and
__delattr__ in the class for similar reasons.
> 2. The "refcount reaches 0" rule in CPython is merely a wonderfully concrete
> way to get across the idea of "destruction occurs in an order consistent
> with a topological sort of the points-to graph". The latter is explicit in
> the BDW collector, which has no refcounts; the topsort concept is applicable
> and thoroughly natural in all languages; refcounts in CPython give an
> exploitable hint about *when* collection will occur, but add no purely
> semantic constraint beyond the topsort requirement (they neatly *imply* the
> topsort requirement). There is no topsort in the presence of cycles, so
> cycles create problems in all languages. The same "throw 'em back at the
> user" approach makes just as much sense from the topsort view as the RC
> view; it doesn't rely on RC at all.
Indeed. I propose to throw it back at the user by calling __del__.
The typical user defines __del__ because they want to close a file,
say goodbye nicely on a socket connection, or delete a temp file.
That sort of thing. This is what finalizers are *for*. As an author
of this kind of finalizer, I don't see why I need to know whether I'm
involved in a cycle or not. I want my finalizer called when my object
goes away, and I don't want my object kept alive by unreachable
--Guido van Rossum (home page: http://www.python.org/~guido/)