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

Peter Otten __peter__ at web.de
Fri Jan 30 03:42:22 EST 2009


Gabriel Genellina wrote:

> But a loop doesn't define a new scope (only "def" and "class" used to
> define one; now generator expressions do too). The new scope is not the
> issue, but the fact that the right and left parts of a gen.expr. are
> evaluated at different times. This wasn't obvious to me -- and still
> isn't. If you rewrite the generator expression as a generator function you
> don't get the same behaviour:
> 
> print "genexpr"
> A = [1,2,3]
> B = 1
> g = (x+B for x in A)
> A = [4,5,6]
> B = 10
> print list(g)
> # output: [11,12,13]
> # A is evaluated at the time g is *defined*
> # B is evaluated at the time g is *iterated*
 
> print "genfunc"

I think it helps understanding if you translate the above to

>>> A = [1,2,3]
>>> B = 1
>>> def f(a):
...     for x in a:
...             yield x+B
...
>>> g = f(A)
>>> A = [4,5,6]
>>> B = 10
>>> print list(g)
[11, 12, 13]

This is not altogether unintuitive, but I think I would prefer if it worked
like

>>> A = [1,2,3]
>>> B = 1
>>> def f(a, b):
...     for x in a:
...             yield x+b
...
>>> g = f(A, B)
>>> A = [4,5,6]
>>> B = 10
>>> list(g)
[2, 3, 4]

i. e. every name were bound early. Of course this wouldn't help with
locals() which would still be called in different scopes.

Peter





More information about the Python-list mailing list