Why doesn't eval of generator expression work with locals?

Jon Clements joncle at googlemail.com
Tue Jan 27 18:59:26 EST 2009


On Jan 27, 11:31 pm, Fabio Zadrozny <fabi... at gmail.com> wrote:
> Hi All,
>
> 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)
>
> Error:
>
> Traceback (most recent call last):
>   File "C:\temp\work\test\src\a.py", line 3, in <module>
>     print eval('all((x == y for x in ar))', global_vars, local_vars)
>   File "<string>", line 1, in <module>
>   File "<string>", line 1, in <genexpr>
> NameError: global name 'y' is not defined
>
> Note that if a list is used instead of a generator it works...
>
> Thanks,
>
> Fabio

I tend to think of it as a generator produces another scope, gets
refactored into something
similar to:

def yourfunc(ar):
    for x in ar:
        yield x == y


Which doesn't work either, however, if you introduce a global y the
function can access it (similar if you add y to your global_vars).
It's basically one of those scope/closure gotcha's along with lambdas
(which was discussed quite heavily recently).

hth,
Jon





More information about the Python-list mailing list