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

Reply via email to