Hi, this is my first post here and I've been following this very interesting discussion as is has developed.
A really short intro about me, I was trained as a computer tech in the early 80's... ie. learned transistors, gates, logic etc... And so my focus tends to be from that of a troubleshooter. I'm medically retired now (not a subject for here) and am looking for something meaningful and rewarding that I can contribute to with my free time.
I will not post often at first as I am still getting up to speed with CVS and how Pythons core works. Hopefully I'm not lagging this discussion too far or adding unneeded noise to it. :-)
So maybe the 'with' keyword should be dropped (again!) in favour of
with_opened(pathname) as f: ...
But that doesn't look so great for the case where there's no variable to be assigned to -- I wasn't totally clear about it, but I meant the syntax to be
with [VAR =] EXPR: BLOCK
where VAR would have the same syntax as the left hand side of an assignment (or the variable in a for-statement).
I keep wanting to read it as:
with OBJECT [from EXPR]: BLOCK
- I'm not sure about the '='. It makes it look rather deceptively
like an ordinary assignment, and I'm sure many people are going to wonder what the difference is between
with f = opened(pathname): do_stuff_to(f)
f = opened(pathname) do_stuff_to(f)
or even just unconsciously read the first as the second without noticing that anything special is going on. Especially if they're coming from a language like Pascal which has a much less magical form of with-statement.
Below is what gives me the clearest picture so far. To me there is nothing 'anonymous' going on here. Which is good I think. :-)
After playing around with Guido's example a bit, it looks to me the role of a 'with' block is to define the life of a resource object. so "with OBJECT: BLOCK" seems to me to be the simplest and most natural way to express this.
def with_file(filename, mode): """ Create a file resource """ f = open(filename, mode) try: yield f # use yield here finally: # Do at exit of 'with <resource>: <block>' f.close
# Get a resource/generator object and use it. f_resource = with_file('resource.py', 'r') with f_resource: f = f_resource.next() # get values from yields for line in f: print line,
# Generator resource with yield loop.
def with_file(filename): """ Create a file line resource """ f = open(filename, 'r') try: for line in f: yield line finally: f.close() # print lines in this file. f_resource = with_file('resource.py') with f_resource: while 1: line = f_resource.next() if line == "": break print line,
The life of an object used with a 'with' block is shorter than that of the function it is called from, but if the function is short, the life could be the same as the function. Then the 'with' block could be optional if the resource objects __exit__ method is called when the function exits, but that may require some way to tag a resource as being different from other class's and generators to keep from evaluating __exit__ methods of other objects. As far as looping behaviors go, I prefer the loop to be explicitly defined in the resource or the body of the 'with', because it looks to be more flexible.
Ron_Adam # "The right question is a good start to finding the correct answer."