Stefan Ram wrote:
Mark Bourne <nntp.mbou...@spamgourmet.com> writes:
In the second case, eval() only gets the globals and immediate locals,

   Yes, I think you are right. Curiously, the following program would
   mislead one to thing that eval /does/ see the intermediate names:

   main.py

def f():
     x = 22
     def g():
         print( x )
         print( eval( 'x' ))
     g()
f()

   output

22
22

   . But "print( x )" had the effect of making that x local.
   Without it, we see the error:

   main.py

def f():
     x = 22
     def g():
         print( eval( 'x' ))
     g()
f()

   error output

NameError: name 'x' is not defined

That is interesting. I know assigning to a value creates a local version (and the non-local then can't be accessed, even before the new value was assigned), but hadn't realised just referencing it brought it into local scope for reading. I guess that's to do with closures, where any variables referenced within the function get bound to the function's scope. e.g. if g() includes a reference to x [as it does in the first example above], and f() returned a reference to g(), calling g() later [from outside of f()] by using that reference would still be able to access x.

With just the eval() call and no other reference to x, the interpreter doesn't know at that time the closure is created that there is a reference to x. At that point, the 'x' is just text in a string. It's only when eval() gets called that it tries to execute that string as Python code - and finds that x isn't in scope.

I'm not all that familiar with the concept of closures, so may have got some of the terminology and details wrong - but it's something along those lines. I'm sure others will correct me...

--
Mark.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to