title: Understanding how Python "Compiles" or "Interprets" Function Objects
body: <p>I have read the following posts but I am still unsure of something.</p>
  
  <ol>
  <li><p><a href="https://stackoverflow.com/questions/3299648/python-compilation-interpretation-process">Python Compilation/Interpretation Process</a></p></li>
  <li><p><a href="https://stackoverflow.com/questions/888100/why-python-compile-the-source-to-bytecode-before-interpreting">Why python compile the source to bytecode before interpreting?</a></p></li>
  </ol>
  
  <p>If I have a single Python file myfunctions.py containing the following code.</p>
  
  <pre><code>x  = 3
  def f():
      print x
      x = 2
  </code></pre>
  
  <p>Then, saying <code>$ python myfunctions.py</code> runs perfectly fine.
  But now make one small change to the above file. The new file looks as shown below.</p>
  
  <pre><code>x  = 3
  def f():
      print x
      x = 2
  f() # there is a function call now
  </code></pre>
  
  <p>This time, the code gives out an error. Now, I am trying to understand this behavior. And so far, these are my conclusions.</p>
  
  <ul>
  <li>Python creates bytecode for <code>x=3</code></li>
  <li>It creates a function object f, quickly scans and has bytecode which talks about the local variables within f's scope but  note that the bytecode for all statements in Python are unlikely to have been constructed.</li>
  <li>Now, Python encounters a function call, it knows this function call is legitimate because the bare minimum bytecode talking about the function object f and its local variables is present.</li>
  <li>Now the interpreter takes the charge of executing the bytecode but from the initial footprint it knows x is a local variable here and says - "Why are you printing before you assign?"</li>
  </ul>
  
  <p>Can someone please comment on this? Thanks in advance. And sorry if this has been addressed before.</p>