En Tue, 27 Jan 2009 22:17:16 -0200, Robert Kern <robert.k...@gmail.com>
escribió:
On 2009-01-27 17:56, Fabio Zadrozny wrote:
Making locals and globals different emulates a function, where the code
will fail:
>>> del y, ar
>>> def f():
... y = 'bar'
... ar = ['foo', 'bar']
... print 'Raw genexp:', all((x==y) for x in ar)
... print 'Evaled:', eval('all((x==y) for x in ar)')
...
>>> f()
Raw genexp: False
Evaled:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in f
File "<string>", line 1, in <module>
File "<string>", line 1, in <genexpr>
NameError: global name 'y' is not defined
Now, the reason that the raw generator expression works inside the
function but not in the eval() is because the raw generator expression
gets lexical scopes rather than just the two locals and globals dicts.
Lexical scoping is not available to the eval() function.
I *thought* I did understand this until I came to this example:
1)
id(globals()), id(locals())
(11239760, 11239760)
# ok, globals and locals are the same at the module level
2)
s = "(id(n) for n in [globals(),locals()])"
list(eval(s))
[11239760, 11239760] # still the same results
3)
s = "(id(n()) for n in [globals,locals])"
list(eval(s))
[11239760, 12583248] # locals() is different
Why do I get a different locals() here? Both expressions define the same
scopes, ok? That is, I'd say that both 2) and 3) define the same, nested
scopes -- why the different results?
Seems that this is unrelated to eval, we can take it out of the question
and still get the same values:
list(id(n) for n in [globals(),locals()])
[11239760, 11239760]
list(id(n()) for n in [globals,locals])
[11239760, 12583248]
Worse, it isn't the new, inner scope of generator expressions. A list
comprehension gives the same results:
[id(n) for n in [globals(),locals()]]
[11239760, 11239760]
[id(n()) for n in [globals,locals]]
[11239760, 12583248]
Seems that it is important *when* those functions are evaluated, but I
don't understand *why*...
--
Gabriel Genellina
--
http://mail.python.org/mailman/listinfo/python-list