I'm having trouble understanding when variables are added to namespaces. I thought I understood it, but my nested function examples below have me very confused.
In each test function below I have an x variable (so "x" is in the namespace of each test function). I also have a nested function in each (innerFunc) that has different flavors of trying to access or assign a variable named "x". --- def test1(): print "running test1..." x = 1 def innerFunc(): print "inner locals():", print "%s" % locals() # x not present (yet) x = 2 print x innerFunc() print "x left as %s\n" % x def test2(): print "running test2..." x = 1 def innerFunc(): print "inner locals():", print "%s" % locals() # x not present innerFunc() print "x left as %s\n" % x def test3(): print "running test3..." x = 1 def innerFunc(): print "inner locals():", print "%s" % locals() # how is x in locals in this case?? print x innerFunc() print "x left as %s\n" % x test1() test2() test3() --- With the nested scope rules, I thought that *at the time of* trying to access an object with a given name, if the name was not available in the namespace of the local function python would then check the namespace of the parent function. My tests above don't seem to match this. Specifically my "at the time of" assumption. What is happening in test3? How is it that "x" ends up in the local namespace before it is ever referenced? It seems that, prior to execution time, the python compiler is "magically" determining that I'm referencing a particular name before assignment and shoving it into the local namespace so it can be used. I did not think the compiler went into function bodies, aside from basic syntax checking. Further confusing me (or confirming the compiler behavior) is adding a 4th test with only one added line... def test4(): print "running test4..." x = 1 def innerFunc(): print "inner locals():", print "%s" % locals() # how is x in locals in this case?? print x x = 2 #ONLY ADDED LINE TO TEST3 innerFunc() print "x left as %s\n" % x In this case I get "UnboundLocalError: local variable 'x' referenced before assignment". I think this means that the compiler (prior to runtime) inspected the code, determined I will do an assignment, decided _not_ to bring the parent's x into the local namespace, and as a result caused the unbound name problem at runtime. It seems that the parent's "x" is brought directly into the local namespace (when appropriate), rather than the namespace lookup just moving up the hierarchy when not found. This is confusing to me and is making me question my understanding of namespace lookups. Are nested scopes a special case where the lookup is handled differently? What if I want to change the value of the parent's "x"? test4 implies that I can't. Have I got this right? Can someone please clarify what is going on? -- http://mail.python.org/mailman/listinfo/python-list