En Fri, 17 Apr 2009 10:55:46 -0300, Scott David Daniels
<scott.dani...@acm.org> escribió:
Robin Becker wrote:
def func(D):
for k in D:
exec '%s=D[%r]' % (k,k)
print i, j, k
print locals()
print i, j, k
if __name__=='__main__':
func(dict(i=1,j=33))
#### end p.py
the compiler package ends up treating i & j as global, whereas the
modern analysis doesn't (and doesn't say they're definitely local
either).
If they are not definitely local, they are non-local. Locals are
determined at function definition time, not function execution time.
So, your expectations about what the exec statement can do above are
mistaken. You may try to work your way around it, but, IMHO, you
will not succeed. If the code above were to work as you wish, every
access to every non-local in code that contains an "exec" would have
to check a "new locals" dictionary just in case the exec added a local.
And that's what happens. In absence of an exec statement, locals are
optimized: the compiler knows exactly how many of them exist, and its
names, just by static code analysis. But when the function contains an
exec statement (or an "import *" statement) this is not possible anymore,
and the compiler has to switch to another strategy and generate code using
a less-optimized approach. Unknown variables are accessed using
LOAD_NAME/STORE_NAME (require a name lookup) instead of the normal
LOAD_FAST/STORE_FAST for local variables and LOAD_GLOBAL/STORE_GLOBAL for
global ones.
Think about what this code would have to do:
> i = j = 42
> def func(D):
> print i, j, k
> for k in D:
> exec '%s=D[%r]' % (k,k)
> print i, j, k
I don't completely understand what you wanted to show, but try this:
py> i = j = 42
py> def f():
... print i, j
... exec "k=1"
... print i, j, k
... exec "i=5"
... print i, j, k
...
py> f()
42 42
42 42 1
5 42 1
py> i
42
py> j
42
py> k
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'k' is not defined
Note that i starts as a global name and after the exec "i=5" it becomes a
local variable; and k is always a local variable even if there is no
explicit assignment to it (except in the exec).
--
Gabriel Genellina
--
http://mail.python.org/mailman/listinfo/python-list