By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,703 Members | 1,230 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,703 IT Pros & Developers. It's quick & easy.

problem with exec and locals()

P: n/a

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 ?

Greetings, Uwe
Jul 1 '08 #1
Share this Question
Share on Google+
4 Replies

P: n/a
Mel
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.

Jul 1 '08 #2

P: n/a
On 1 Jul., 15:15, Mel <mwil...@the-wire.comwrote:
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
Jul 11 '08 #3

P: n/a
Uwe Schmitt wrote:
>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 ???
Hm, the documentation has an explicit warning:

http://docs.python.org/lib/built-in-funcs.html#l2h-47

"""
locals( )
Update and return a dictionary representing the current local symbol table.
Warning: The contents of this dictionary should not be modified; changes
may not affect the values of local variables used by the interpreter.
"""

By the way, the local namespace is affected if you don't provide it
explicitly:
>>def f():
.... exec "a=42"
.... print a
.... a = "whatever"
....
>>f()
42

Peter

Jul 11 '08 #4

P: n/a
En Fri, 11 Jul 2008 03:51:39 -0300, Uwe Schmitt
<ro*************@googlemail.comescribi�:
On 1 Jul., 15:15, Mel <mwil...@the-wire.comwrote:
>rocksportrockerwrote:
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,

Thanks for your answer. I wonder if this is a bug, or did I miss
something
in the docs ???
Read the warnings in the docs for the locals() builtin function:
http://docs.python.org/lib/built-in-funcs.html#l2h-47
and the execfile function:
http://docs.python.org/lib/built-in-funcs.html#l2h-26

--
Gabriel Genellina

Jul 11 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.