A Function's name during its definition
Mark Bourne
nntp.mbourne at spamgourmet.com
Tue Feb 7 18:04:54 EST 2023
Stefan Ram wrote:
> Mark Bourne <nntp.mbourne at 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.
More information about the Python-list
mailing list