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