[Tutor] eval use (directly by interpreter vs with in a script)

Dave Angel d at davea.name
Sun Nov 2 22:00:31 CET 2014


On 11/02/2014 03:01 PM, Alex Kleider wrote:
> I'm puzzled by the following behaviour:
>
> The following works as I expect:
>
> alex at x301:~/Python$ python3
> Python 3.4.0 (default, Apr 11 2014, 13:05:18)
> [GCC 4.8.2] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> code = """\
> ... s1 = 'first'
> ... s2 = 'second'
> ... """
>>>> exec(code)
>>>> s1
> 'first'
>>>> s2
> 'second'
>>>>
>
> ..the following script also behaves as I expect:
> alex at x301:~/Python$ cat test.py
> #!/usr/bin/env python3
> """
> Testing use of exec().
> """
> code = """\
> s1 = 'first'
> s2 = 'second'
> """
> exec(code)
> print(s1)
> print(s2)
> alex at x301:~/Python$ ./test.py
> first
> second
>
> ... but this one doesn't:
> alex at x301:~/Python$ cat t1.py
> #!/usr/bin/env python3
> """
> Testing use of exec().
> """
> code = """\
> s1 = 'first'
> s2 = 'second'
> """
>
> def main():
>      exec(code)
>      print(s1)
>
> if __name__ == "__main__":
>      main()
> alex at x301:~/Python$ ./t1.py
> Traceback (most recent call last):
>    File "./t1.py", line 15, in <module>
>      main()
>    File "./t1.py", line 12, in main
>      print(s1)
> NameError: name 's1' is not defined
>
> Any light that can be shed onto this would be appreciated.
> Alex
>

I'll assume CPython.  Other implementations may vary.

Sure.  Inside a function (whether in interpreter or in a script, no 
difference), there are a fixed set of local variables, that the compiler 
has identified.  You can't add more by any means, whether by using 
locals(), or exec(), or other trickery.

Those variables are referred to by number, so it's very much like slots 
in a class.  There is no name lookup at run time for function-locals, 
which saves time and probably space.

You could probably make something work using the global statement, but I 
don't know whether exec() would even notice such a thing.  You also 
could pass custom local and global namespaces, and fake something that way.

Real question is what you're trying to do.  eval() and exec() are to be 
avoided if possible, so the solutions are not necessarily the easiest.

-- 
DaveA


More information about the Tutor mailing list