three-liner: reposted from python-dev for more feedback. it suggests to add the weakattr class to the standard weakref.py module. comments are welcome.
[ http://article.gmane.org/gmane.comp.python.devel/81875 ] From: tomer filiba <tomerfiliba <at> gmail.com> Subject: weakattr Newsgroups: gmane.comp.python.devel Date: 2006-07-01 13:49:46 GMT (2 days, 3 hours and 12 minutes ago) 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 -- http://mail.python.org/mailman/listinfo/python-list