Singleton generators as code blocks

D

Dave Benjamin

Hey all,

I was just reflecting upon the old code block debate, and the thought
occurred to me that Python really does have a form of code blocks in its
implementation of generators. It was a pretty natural conclusion, and I'm
not sure why I didn't think of it before. For instance, compare Python's
generator-style iteration versus Ruby's codeblock-style iteration:

Python:
for item in seq:
print item

Ruby:
seq.each { |item|
puts item
}

Now, aside from the difference in mechanics, these two methods basically
accomplish the same thing. "seq" could be a regular list, or it could be a
lazy sequence. The syntax remains the same.

One of the simplest arguments in favor of codeblocks (or macros, but I'm not
going to go there <grin>) was the ability to write a function like
"with_open_file" that would open a file, perform some action on the file,
and then close the file automatically. I'm going to use this as an example
because of its simplicity, not because I think that there is an overwhelming
need for such a function.

In Python, I was able to implement a generator version quite simply. It
seemed so obvious that I thought maybe there was a thread in the past where
this was already mentioned; if so, forgive me for stating the obvious:

def open_file(filename, mode='r'):
f = file(filename, mode)
yield f
print 'closing...'
f.close()

for f in open_file('input.txt'):
print f.read()

The above code prints the conntents of the file "input.txt", then the string
"closing...", and then closes the file.

This seems to illustrate that generators and codeblock-accepting functions
are really very similar, and that maybe codeblocks wouldn't really add much
of anything to Python after all. I still have to wonder if maybe I'm missing
something here...

Has anyone used this sort of "singleton generator" technique?
 
J

Jp Calderone

Hey all,

[snip]

In Python, I was able to implement a generator version quite simply. It
seemed so obvious that I thought maybe there was a thread in the past where
this was already mentioned; if so, forgive me for stating the obvious:

def open_file(filename, mode='r'):
f = file(filename, mode)
yield f
print 'closing...'
f.close()

for f in open_file('input.txt'):
print f.read()

The above code prints the conntents of the file "input.txt", then the string
"closing...", and then closes the file.

This seems to illustrate that generators and codeblock-accepting functions
are really very similar, and that maybe codeblocks wouldn't really add much
of anything to Python after all. I still have to wonder if maybe I'm missing
something here...

Has anyone used this sort of "singleton generator" technique?

This is a pretty nifty approach, but it seems to have (at least?) one serious
drawback. If the body of the loop raises an exception, the generator is
never resume, and the cleanup (or whatever) is never run.

A way to reformulate the above without losing its conciseness eludes me
currently.

Jp
 
D

Dave Benjamin

This is a pretty nifty approach, but it seems to have (at least?) one serious
drawback. If the body of the loop raises an exception, the generator is
never resume, and the cleanup (or whatever) is never run.

Yeah, that is indeed a problem. That was in the back of my mind when I wrote
that disclaimer (that it's just an example), but you summed it up very well.
A way to reformulate the above without losing its conciseness eludes me
currently.

Me too. The obvious solution would be to wrap the body in a try/finally, but
then, I guess we're right back where we started. ;)

Thanks for the feedback.
 
G

Greg Ewing (using news.cis.dfn.de)

Jp said:
This is a pretty nifty approach, but it seems to have (at least?) one serious
drawback. If the body of the loop raises an exception, the generator is
never resume, and the cleanup (or whatever) is never run.

If open_file were implemented as a class rather than a
generator, maybe the cleanup could be implemented with its
__del__ method.

Or maybe the iterator protocol should include a __cleanup__
or __finally__ method that the for-loop invokes before leaving
via a break or exception?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top