[Python-Dev] Possible resolution of generator expression
variable capture dilemma
Phillip J. Eby
pje at telecommunity.com
Wed Mar 24 12:46:10 EST 2004
At 08:24 AM 3/24/04 -0800, Guido van Rossum wrote:
>Phillip shows some examples involving inner functions defined inside
>the for loop. But in current Python these examples work just as well
>if the function is defined *outside* the loop (as long as no default
>argument values are needed):
>
> > for x in 1,2,3:
> > def y():
> > print z
> > z = x * 2
> > y()
>
>is the same as
>
> def y():
> print z
> for x in 1, 2, 3:
> z = x*2
> y()
>
>That would change under Phillip's proposal.
Hm. I was viewing it a bit differently. In effect, I was treating the
loop as a new "nested scope", so a function defined within a loop would
have different variable capture than one defined outside a loop.
>There are similar examples that would break under Greg's original
>proposal: just use the loop variable in the function, e.g.:
Right, I mentioned at the end that the issue with my proposal was also
applicable to Greg's.
>All this is just more reason to put this one off until 3.0.
I agree, and withdraw my support for early binding in generator
expressions, despite Tim's example. Instead, we should have a consistent
failure under "practicality beats purity". That is, a straightforward
translation of:
pipe = source
for p in predicates:
# add a filter over the current pipe, and call that the new pipe
pipe = e for e in pipe if p(e)
to:
pipe = source
for p in predicates:
def __():
for e in pipe:
if p(e):
yield e
# add a filter over the current pipe, and call that the new pipe
pipe = __()
produces exactly the same broken behavior in today's Python. The solution,
of course is:
def ifilter(pred,pipe):
for e in pipe:
if pred(e):
yield e
pipe = source
for p in predicates:
# add a filter over the current pipe, and call that the new pipe
pipe = ifilter(p,pipe)
More information about the Python-Dev
mailing list