title: Variable scope and name resolution in Python
body: <p>I think that I fundamentally don't understand how Python does things like variable scope and name resolution. In particular, the fact that the function <code>broken()</code> below doesn't work really surprises me. And, though I've fished around the web for awhile looking for a helpful explanation, but I still don't get it. Can anyone explain or link to a good description of how this stuff works in Python, with enough details that it will seem obvious why <code>broken()</code> doesn't work after reading the relevant materials?</p>
  
  <pre><code># Why does this code work fine
  def okay0():
      def foo():
          L = []
          def bar():
              L.append(5)
          bar()
          return L
      foo()
  
  # and so does this
  def okay1():
      def foo():
          def bar():
              L.append(5)
          L = []
          bar()
          return L
      foo()
  
  # but the following code raises an exception?
  def broken():
      def foo():
          L = []
          bar()
          return L
      def bar():
          L.append(5)
      foo()
  
  # Example
  test_list = [okay0, okay1, broken]
  for test_function in test_list:
      try:
          test_function()
      except:
          print("broken")
      else:
          print("okay")
  </code></pre>