Why doesn't eval of generator expression work with locals?
Robert Kern
robert.kern at gmail.com
Tue Jan 27 19:17:16 EST 2009
On 2009-01-27 17:56, Fabio Zadrozny wrote:
> On Tue, Jan 27, 2009 at 9:51 PM, James Mills
> <prologic at shortcircuit.net.au> wrote:
>> On Wed, Jan 28, 2009 at 9:31 AM, Fabio Zadrozny<fabiofz at gmail.com> wrote:
>>> Anyone knows why the code below gives an error?
>>>
>>> global_vars = {}
>>> local_vars = {'ar':["foo", "bar"], 'y':"bar"}
>>> print eval('all((x == y for x in ar))', global_vars, local_vars)
>> y is undefined in your generator expression.
>
> Yes... but why? It seems to me like it should be defined (if I put the
> locals in the globals it finds it... seems very weird to me)
I think you can work around your problem by using the same dictionary for both
locals and globals. The locals/globals distinction is not useful in your
circumstances. For example, the Python interpreter has these the same:
>>> globals() is locals()
True
And that makes the code work:
>>> y = 'bar'
>>> ar = ['foo', 'bar']
>>> all((x==y) for x in ar)
False
>>> eval('all((x==y) for x in ar)')
False
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.
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list