title: How do yield works in Python C code, good & bad part
body: <p>Recently I've been looking into the code of Python. I know how to use generators (next, send and etc..), but it's fun to understand it by reading the Python C code.</p>
  
  <p>I found the code in <a href="http://hg.python.org/cpython/file/b3f4616b9a94/Objects/genobject.c" rel="noreferrer">Object/genobject.c</a>, and it's not that hard (but still not easy) to understand. So I want to know how it really works, and make sure I do not have a misunderstanding about generators in Python.</p>
  
  <p>I know everything calls</p>
  
  <pre><code>static PyObject *
  gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
  </code></pre>
  
  <p>and the result is returned from <code>PyEval_EvalFrameEx</code> which looks like it's a dynamic frame struct, could I understand it as <code>stack</code> or something?</p>
  
  <p>Ok, It looks like Python stores some context in memory (am I right?). It looks like every time we use yield it creates a generator, and stores the context in memory, although not all of the functions and vars.</p>
  
  <p>I know if I have big loop or big data to parse, yield is amazing, it saves a lot of memory and make it simple. But some of my workmates like to use yield everywhere, just like return. It's not easy to read and understand the code, and Python stores context for most of the function that may never be called again. Is it a bad practice?</p>
  
  <p>So, the questions are:</p>
  
  <ol>
  <li>How does <code>PyEval_EvalFrameEx</code> work.</li>
  <li>Memory use of yield.</li>
  <li>Is it bad practice for using yield everywhere.</li>
  </ol>
  
  <p>And I found if I have a generator, function <code>gen_send_ex</code> will be called twice, why?</p>
  
  <pre><code>def test():
      while 1:
          yield 'test here'
  
  test().next()
  </code></pre>
  
  <p>It will call <code>gen_send_ex</code> twice, first time with no args, with args the second time, and get the result.</p>
  
  <p>Thanks for your patience.</p>