Why doesn't eval of generator expression work with locals?
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Tue Jan 27 21:06:17 EST 2009
En Tue, 27 Jan 2009 22:17:16 -0200, Robert Kern <robert.kern at 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
More information about the Python-list
mailing list