[Python-ideas] for line in input with open(path) as input...

Shane Green shane at umbrellacode.com
Sat Feb 2 14:21:38 CET 2013


Sorry, I was definitely unclear: I understand that isn't their sole 
purpose, and what role they play, in both the iteration examples and 
others, and I don't mean to "object" to anything, nor was I suggesting 
context-manager current implementation was uneeded, etc.

My point is that, in the examples I listed, the sole purpose of the 
context-manager is to provide a context the for loop will execute in.

with manager as context:
     # No statements here...
     for items in context:
        # blah
     # no statements here...

I was suggesting this scenario, wherein the body of a for loop is, in 
fact, the block of code that acts upon some resource or set of resource 
being managed by a context manager, might be common enough to warrant a 
closer look, as the more "pythonic" approach might accept the for loop's 
body as the with statement's code block context.

with open(file) as input:
     # why have input exist here, if it's not used, other than...
     for line in input:
        # do something...
        # why have input--the context--exist outside of me?
     # why have input exist here?

And finally, why define the outer with block, for the sole pupose of 
containing the inner "for in.." loop's block?






> Steven D'Aprano <mailto:steve at pearwood.info>
> February 2, 2013 4:46 AM
> On 02/02/13 22:46, Shane Green wrote:
>> with open(path) as input:
>> for line in input:
>> do(line)
>>
>> Using with to create reference to opened file returned by open() so 
>> it could temporarily be assigned to input for the sole purpose of 
>> iterating its contents never sat very well with me.
>
> It's not the *sole* purpose. If all you want it to iterate over the 
> file, you can do this:
>
> for line in open(path):
>     ...
>
>
> and no context manager is created. The context manager is also 
> responsible for closing the file immediately you exit the block, 
> without waiting for the caller to manually close it, or the garbage 
> collector to (eventually) close it. So it is not *solely* for iteration.
>
> File context managers can also be used for more than just iteration:
>
> with open(path) as input:
>     text = input.read()
>
>
> with open(path, 'r+') as output:
>     output.write('ZZ')
>
> and so forth.
>
>
>> * The context manager returned by open() exists only to create the
>> context and return reference "input";
>> * the context and code block created by the "with" only exists for
>> inner "for" loop's code block to execute in.
>
>
> I don't understand that objection. As I see it, that's a bit like 
> saying "the len function exists only to get the length of objects". 
> What did you expect the context manager to exist for if not to do the 
> things you say?
>
> What am I missing?
>
>
>
>
> Shane Green <mailto:shane at umbrellacode.com>
> February 2, 2013 3:46 AM
> with open(path) as input:
>     for line in input:
>         do(line)
>
> Using with to create reference to opened file returned by open() so it 
> could temporarily be assigned to input for the sole purpose of 
> iterating its contents never sat very well with me.
>
>   * The context manager returned by open() exists only to create the
>     context and return reference "input";
>   * the context and code block created by the "with" only exists for
>     inner "for" loop's code block to execute in.
>
> Now, given a generator function:
>
> def iterwith(cm):
>     with cm as context:
>         if context is None:
>             context = cm
>         for item in context:
>             yield item
>
> The previous code can be turned into:
>
> for line in iterwith(open(path)):
>     do(line)
>
> So, questions:
>     - Is there anything inherently wrong with the idea, or does it exist?
>     - Is it a generally useful tool, or are the examples limited to files?
>     - Is it possible a more general mechanism could have value, such as:
>
> for line in file with open(path) as file:
>     do(line)
>
>
> The preceding could be leveraged to different effect:
>
> for line in file with locked(path):
> write(path + ".out", line)
>
> Or,
>     for line in input with nested(open(path),lock,open(opath)) as 
> input,locked,output:
>         output.write(line)
>
> To revisit the original purpose of "with", this seems to cleanly 
> address a very common scenario wherein:
>
> resource = create_resource()
> try:
>     for item in resource:
>         do_something(resource, item)
> except:
>     raise
> finally:
>     cleanup()
>
> # Standard with approach...
> with create_resource() as resource:
>     for item in resource:
>         do_something(resource, item)
>
> # With for loop as context...
> for item in resource with create_resource() as resource:
>     do_something(resource, item)
>
> And, given the translation into statements, maybe even crazy stuff...
>
> [line for line in file with open(path) as file]
>
> J/K, I think.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20130202/3dab7dd7/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: compose-unknown-contact.jpg
Type: image/jpeg
Size: 770 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20130202/3dab7dd7/attachment.jpg>


More information about the Python-ideas mailing list