[Python-Dev] weakattr (original) (raw)

tomer filiba tomerfiliba at gmail.com
Sat Jul 1 15:49:46 CEST 2006


weakattr (weak attributes) are attributes that are weakly referenced 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-dev/attachments/20060701/b174e77e/attachment.htm



More information about the Python-Dev mailing list