Using weakrefs instead of __del__

R

Rhamphoryncus

I know __del__ can't be relied on to do cleanup, so I'm thinking of
using a globally reachable weakref to do the job, like so:

import weakref

class Foo:
def __init__(self, *args, **kwargs):
self.__realfoo = RealFoo(self, *args, **kwargs)
def blah(self):
return self.__realfoo.blah()

class RealFoo:
refs = set()
def __init__(self, front):
self.refs.add(weakref.ref(front, self.cleanup))
def blah(self):
print "Blah!"
def cleanup(self, ref):
print "Doing cleanup"
self.refs.remove(ref)

Is there any reason why this wouldn't work? Can it be used as a
general replacement for anything that needs __del__? Even in Jython or
other alternative implementations?

Some issues I know about:
* The weakref must be globally reachable (as I do with the above code)
to make sure it doesn't get deleted at the same time Foo does, because
python would not call the callback if that were the case.
* I can't use any getattr tricks to wrap .blah() because Foo().blah()
would only use a method bound to RealFoo, thus allowing Foo to be
deallocated and .cleanup() to be called before the method itself is.
Unfortunately my metaclass-fu is too weak to figure out something
without that problem.
* I've no idea what will happen when the interpreter exits, but I
don't imagine it would matter much for most uses.
 
G

Greg Ewing

Rhamphoryncus said:
class RealFoo:
refs = set()
def __init__(self, front):
self.refs.add(weakref.ref(front, self.cleanup))
def blah(self):
print "Blah!"
def cleanup(self, ref):
print "Doing cleanup"
self.refs.remove(ref)

That won't work, because the bound method you're using as
the cleanup function contains a reference to the object,
preventing it from being deallocated.

The weakref callback is only called *after* the object has
been deallocated. If you try to contrive a way of passing the
object to the callback, you will just end up keeping it alive.
To use a weakref as a finalizer, the information needed
for finalization needs to be kept somewhere outside of
the object triggering the finalization.

This may be what you were trying to achieve by separating
your object into a Foo and a RealFoo. If that's so, you
should have made the weak ref point to the Foo, not the
RealFoo.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top