does python have useless destructors?

Humpdydum oliver.schoenborn at utoronto.ca
Thu Jun 10 19:42:03 CEST 2004


"David Turner" <dkturner at telkomsa.net> wrote in message
news:e251b7ba.0406100011.39a795e1 at posting.google.com...
>
> This makes me sad.  But there is some hope in the following pattern,
> although it can be quite awkward:
>
> def with_file(fname, mode, oper):
>     f = open(fname, mode);
>     try:
>         oper()
>     finally:
>         f.close()
>
> Of course, this can very quickly turn your code into so much
> functional goo.  That's not necessarily a bad thing, as Lisp
> programmers can attest...  But it's still not quite as powerful as
> RAII.

I tried out a technique yesterday that shows it's possible to have reliable
'finalization' in Python, and not surprisingly it relies on try/finally (how
else...), BUT user no longer has to use this construct (it's automatic). I
posted on python-dev to get feedback about whether or not the technique
could be put right into the interpreter, which would improve performance and
robustness.

In any case, the module is currently called *scope*. The usage idiom looks
like (pythonic pseudo-code):

class YourClass(scope.NeedsFinalization):
    ... nothing else to change, except:
    def _finalize(self):
        ... do the clean-up

def yourFunc(...):
    # do stuff that uses one or more instances of YourClass
    # that need some form of "clean-up"
    ...

yourFunc = scope.ScopeGuarded(yourFunc)

# do some calls to yourFunc(); whether exception or normal return,
# your instances are guaranteed to be cleaned-up before returning
yourFunc(...)

I used the term 'finalization' even though technically not rigorous.
Conceptually that's what it is because after the call to _finalize() the
object should be assumed in an unusable state.

Some advantages over try/finally:
- Coder of class makes explicit by base class that finalizaiton is
important, no need to remember to document.
- User of class knows just by looking at class def, can't overlook  a
sentence saying "call this-that when done with object"
- Some error checking can be done to decrease likelyhood of user forgetting
the scope-guarding rebind or of asking for finalization before refcount 0.
- Recursive functions need no try/finally

There are a couple of limitations in the current implementation (e.g. make
it work for global scope exit,
and methods, don't know yet about thread safety) but you get the idea. The
*scope* module would make it trivial to create some modules that wrapped
some of the standard python library classes in scope.NeedsFinalization.

If you'd like to comment on the code send me an email and I'll email
scope.py back to you.

Oliver





More information about the Python-list mailing list