[Python-ideas] With clauses for generator expressions
Phil Connell
pconnell at gmail.com
Thu Nov 15 08:35:55 CET 2012
On Wed, Nov 14, 2012 at 07:44:44PM -0800, Andrew Barnert wrote:
> First, I realize that people regularly propose with expressions. This is not the
> same thing.
>
> The problem with the with statement is not that it can't be postfixed
> perl-style, or used in expressions. The problem is that it can't be used with
> generator expressions.
>
> Here's the suggestion:
>
> upperlines = (lines.upper() for line in file with open('foo', 'r') as file)
While this looks very clean, how do you propose the following should be written
as a generator expression?
def foo():
with open('foo') as f:
for line in f:
if 'bar' in line:
yield line
An obvious suggestion is as follows, but I'm not totally convinced about the
out-of-order with, for and if clauses (compared with the equivalent generator)
(line
for line in f
if bar in 'line'
with open('foo') as f)
Cheers,
Phil
>
> This would be equivalent to:
>
> def foo():
> with open('foo', 'r') as file:
> for line in file:
> yield line.upper()
> upperlines = foo()
>
> The motivation is that there is no way to write this properly using a with
> statement and a generator expression—in fact, the only way to get this right is
> with the generator function above. And almost nobody ever gets it right, even
> when you push them in the right direction (although occasionally they write a
> complex class that has the same effect).
>
> That's why we still have tons of code like this lying around:
>
> upperlines = (lines.upper() for line in open('foo', 'r'))
>
> Everyone knows that this only works with CPython, and isn't even quite right
> there, and yet people write it anyway, because there's no good alternative.
>
> The with clause is inherently part of the generator expression, because the
> scope has to be dynamic. The file has to be closed when iteration finishes, not
> when creating the generator finishes (or when the generator is cleaned up—which
> is closer, but still wrong).
>
> That's why a general-purpose "with expression" wouldn't actually help here; in
> fact, it would just make generator expressions with with clauses harder to
> parse. A with expression would have to be statically scoped to be general.
>
> For more details, see this:
>
> http://stupidpythonideas.blogspot.com/2012/11/with-clauses-for-generator-expressions.html
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
More information about the Python-ideas
mailing list