title: How python handles object instantiation in a ' for' loop
body: <p>I've got a highly complex class :</p>
  
  <pre><code>class C:
      pass
  </code></pre>
  
  <p>And I've got this test code :</p>
  
  <pre><code>for j in range(10):
      c = C()
      print c
  </code></pre>
  
  <p>Which gives :</p>
  
  <pre><code>&lt;__main__.C instance at 0x7f7336a6cb00&gt;
  &lt;__main__.C instance at 0x7f7336a6cab8&gt;
  &lt;__main__.C instance at 0x7f7336a6cb00&gt;
  &lt;__main__.C instance at 0x7f7336a6cab8&gt;
  &lt;__main__.C instance at 0x7f7336a6cb00&gt;
  &lt;__main__.C instance at 0x7f7336a6cab8&gt;
  &lt;__main__.C instance at 0x7f7336a6cb00&gt;
  &lt;__main__.C instance at 0x7f7336a6cab8&gt;
  &lt;__main__.C instance at 0x7f7336a6cb00&gt;
  &lt;__main__.C instance at 0x7f7336a6cab8&gt;
  </code></pre>
  
  <p>One can easily see that Python switches on two different values.
  In some cases, this can be catastrophic (for example if we store the objects in some other complex object).</p>
  
  <p>Now, if I store the objects in a List :</p>
  
  <pre><code>lst = []
  for j in range(10):
      c = C()
      lst.append(c)
      print c
  </code></pre>
  
  <p>I get this :</p>
  
  <pre><code>&lt;__main__.C instance at 0x7fd8f8f7eb00&gt;
  &lt;__main__.C instance at 0x7fd8f8f7eab8&gt;
  &lt;__main__.C instance at 0x7fd8f8f7eb48&gt;
  &lt;__main__.C instance at 0x7fd8f8f7eb90&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ebd8&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ec20&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ec68&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ecb0&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ecf8&gt;
  &lt;__main__.C instance at 0x7fd8f8f7ed40&gt;
  </code></pre>
  
  <p>Which solves the case.</p>
  
  <p>So now, I have to ask a question...
  Does anyone could explain with complex words (I mean, deeply) how Python behave with the objects references ?
  I suppose, it is a matter of optimization (to spare memory, or prevent leaks, ...)</p>
  
  <p>Thank a lot.</p>
  
  <p><strong>EDIT :</strong> 
  Ok so, let's be more specific. I'm quite aware that python has to collect garbage sometimes... But, in my case :</p>
  
  <p>I had a list returned by a Cython defined class : class 'Network' that manages a 'Node's list (both Network and Node class are defined in a <code>Cython extension</code>). Each Node has a an object [then casted into (void *)] 'userdata' object. The Nodes list is populated from inside cython, while the UserData are populated inside the Python script. So in python, I had the following :</p>
  
  <pre><code>...
  def some_python_class_method(self):
      nodes = self.netBinding.GetNetwork().get_nodes()
      ...
      for item in it:
          a_site = PyLabSiteEvent()
          #l_site.append(a_site)        # WARN : Required to get an instance on 'a_site' 
                                        #        that persits - workaround...
      item.SetUserData(a_site)
  </code></pre>
  
  <p>Reusing this node list later on in the same python class using the same cython getter :</p>
  
  <pre><code>def some_other_python_class_method(self, node):
      s_data = node.GetUserData()
      ...
  </code></pre>
  
  <p>So, it seems that with the storage made in the node list's UserDatas, my python script was completely blind and was freeing/reusing memory. It worked by referencing a second time (but apparently a first one for python side), using an additional list (here : 'l_site').
  This is why I had to know a bit more about Python itself, but it seems that the way I implemented the communication between Python and <code>Cython</code> is responsible for the issues a had to face.</p>