[Python-Dev] code blocks using 'for' loops and generators
Brian Sabbey
sabbey at u.washington.edu
Sun Mar 13 02:43:23 CET 2005
On Sat, 12 Mar 2005, Steven Bethard wrote:
> Brian Sabbey <sabbey at u.washington.edu> wrote:
>> I agree that this is a confusing way to use generators. But it is the
>> expected way to use "code blocks" as found in other languages. It would
>> take some getting used to that 'for' can be used this way, but I think it
>> would be worth it.
>
> I guess I need some more convincing... I don't find your approach[*], e.g.
>
> def pickled_file(name):
> f = open(name, 'r')
> data yield pickle.load(f)
> f.close()
> f = open(name, 'w')
> pickle.dump(data, f)
> f.close()
>
> for data in pickled_file('greetings.pickle'):
> data.append('hello')
> data.append('howdy')
> continue data
>
> any clearer than, say:
>
> class PickledFile(object):
> def __init__(self, name):
> self.name = name
> f = open(self.name, 'r')
> self.data = pickle.load(f)
> f.close()
> def close(self):
> f = open(self.name, 'w')
> pickle.dump(self.data, f)
> f.close()
>
> p = PickledFile('greetings.pickle')
> p.data.extend(['hello', 'howdy'])
> p.close()
>
> Note that I'm not using the iteration construct (for-in) because I'm
> not really doing an iteration here. Pehaps I could be taught to read
> for-in otherwise, but without an obvious benefit for doing so, I'm
> really not inclined to.
In the real world, I need to lock and unlock the pickled files. So if I
forget to call p.close(), then it would be a problem. I would need a
try/finally block. If I could use the above 'for' loop approach, I am
able to encapsulate the try/finally code.
This is the same problem that is addressed in PEP 310. Copied from the
PEP, here is the basic idea:
The syntax of a 'with' statement is as follows::
'with' [ var '=' ] expr ':'
suite
This statement is defined as being equivalent to the following
sequence of statements:
var = expr
if hasattr(var, "__enter__"):
var.__enter__()
try:
suite
finally:
var.__exit__()
I prefer re-using the 'for' loop for this purpose because it allows the
problem to be solved in a general way by re-using a structure with which
most users are already familiar, and uses generators, which are easier to
use in this case than defining a class with __exit__, __enter__, etc.
-Brian
More information about the Python-Dev
mailing list