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. -- http://mail.python.org/mailman/listinfo/python-list