[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