problem with exec and locals()

Mel mwilson at the-wire.com
Tue Jul 1 09:15:27 EDT 2008


rocksportrocker wrote:

> 
> 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.




More information about the Python-list mailing list