by their containing object. they are very useful for cyclic references --
an object that holds a reference to itself.
when a cyclic reference is found by the GC, the memory may be
freed, but __del__ is not called, because it's impossible to tell which
__del__ to call first. this is an awkward asymmetry with no clean
solution: most such objects provide a "close" or "dispose" method
that must be called explicitly.
weakattrs to solve this problem, by providing a "magical" attribute
that "disappears" when the attribute is no longer strongly-referenced.
you can find the code, as well as some examples, on this link
http://sebulba.wikispaces.com/recipe+weakattr
since the stdlib already comes with weakref.py, which provides
higher level concepts over the builtin _weakref module, i'd like to
make weakattr a part of it.
it's only ~20 lines of code, and imho saves the trouble of explicitly
releasing the resource of un__del__able objects.
i think it's useful. here's a snippet:
>>> from weakref import weakattr
>>>
>>> class blah(object):
... yada = weakref()
...
>>> o1 = blah()
>>> o2 = blah()
>>> o1.yada = o2
>>> o2.yada = o1
o1.yada is a *weakref* to o2, so that when o2 is no longer
strongly-referenced...
>>> del o2
o1.yada "magically" disappears as well.
>>> o1.yada
... AttributeError(...)
since the programmer explicitly defined "yada" as a weakatt, he/she
knows it might "disappear". it might look awkward at first, but that's
exactly the *desired* behavior (otherwise we'd just use the regular
strong attributes).
another thing to note is that weakattrs are likely to be gone only
when the object's __del__ is already invoked, so the only code that
needs to take such precautions is __del__ (which already has some
constraints)
for example:
>>> class blah(object):
... me = weakattr()
...
... def __init__(self):
... self.me = self
...
... def something(self):
... # we can rest assure me exists at this stage
... print self.me
...
... def __del__(self):
... # by the time __del__ is called, "me" is removed
... print "me exists?", hasattr(self, "me")
...
>>> b = blah()
>>> b.me
<__main__.blah object at 0x00C0EC10>
>>> b.something()
<__main__.blah object at 0x00C0EC10>
>>> del b
>>> import gc
>>> gc.collect()
me exists? False
0
>>>
-tomer
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com