problem with exec and locals()
Uwe Schmitt
rocksportrocker at googlemail.com
Fri Jul 11 02:51:39 EDT 2008
On 1 Jul., 15:15, Mel <mwil... at the-wire.com> wrote:
> rocksportrockerwrote:
>
> > Hi,
>
> > the following code does not work until I ommit the "a=0" statement.
>
> > def test():
> > exec "a=3" in locals()
> > print a
> > a=0
>
> > test()
>
> > print raises:
> > UnboundLocalError: local variable 'a' referenced before
> > assignment
>
> > Can anybody explain what is going wrong here ?
>
> AFAIK, local variables are implemented rather like __slots__ in new-style
> classes. This is a very valuable efficiency measure, but it can cause this
> kind of trouble. Without `a=0`, the bytecode compiler makes no slot for a,
> and dis.dis shows the following bytecode for test:>>> dis.dis (test)
>
> 2 0 LOAD_CONST 1 ('a=3')
> 3 LOAD_NAME 0 (locals)
> 6 CALL_FUNCTION 0
> 9 DUP_TOP
> 10 EXEC_STMT
>
> 3 11 LOAD_NAME 1 (a)
> 14 PRINT_ITEM
> 15 PRINT_NEWLINE
> 16 LOAD_CONST 0 (None)
> 19 RETURN_VALUE
>
> At address 11, LOAD_NAME 1(a) gets the value that was set by exec.
>
> With a=0, the code is>>> dis.dis(test2)
>
> 2 0 LOAD_CONST 1 ('a=4')
> 3 LOAD_NAME 0 (locals)
> 6 CALL_FUNCTION 0
> 9 DUP_TOP
> 10 EXEC_STMT
>
> 3 11 LOAD_FAST 0 (a)
> 14 PRINT_ITEM
> 15 PRINT_NEWLINE
>
> 4 16 LOAD_CONST 2 (0)
> 19 STORE_FAST 0 (a)
> 22 LOAD_CONST 0 (None)
> 25 RETURN_VALUE
>
> and here, the value of a is found in slot 0 via LOAD_FAST. Slot 0 is used
> because a=0 forced a to be a local variable.
>
> Apparently, exec in locals() knows nothing about slots (because locals() is
> the only dictionary in the universe where slots would be involved ? --
> perhaps not, but close).
>
> Mel.
Thanks for your answer. I wonder if this is a bug, or did I miss
something
in the docs ???
Greetings, Uwe
More information about the Python-list
mailing list