[Python-Dev] code blocks using 'for' loops and generators

Steven Bethard steven.bethard at gmail.com
Sat Mar 12 23:15:11 CET 2005


Brian Sabbey <sabbey at u.washington.edu> wrote:
> (I) Give generators a __call__ method as an alternative to 'next'.
> Method __call__ should take a single parameter: a function.  Using
> __call__ will cause the generator to start executing normally, but when a
> 'yield' is reached, the generator will invoke the function passed to
> __call__ instead of activating the currently implemented 'yield'
> mechanism.

The goals behind this seem a lot like the goals of PEP 288[1].  I
remember discussions suggesting code like:

def gen():
    a, b, c=3 = yield 1
    yield a + b*c

g = gen()
print g.next() # prints 1
print g.next(1, 2) # prints 7

But as you can see, this creates a weird asymmetry because the last
yield throws away its arguments, and depending on how the generator is
written, different calls to next may require a different number of
arguments.  This means that, unless the code is extremely well
documented, you have to read the source code for the generator to know
how to call it.

Because of these and other complications, I believe the PEP is now
lobbying for a way to get the generator instance object and a way to
cause an exception to be thrown from outside the generator.  Take a
look and see if the PEP might meet your needs -- I haven't seen much
action on it recently, but it seems much less invasive than your
proposal...

> As an example of the syntax I am suggesting, here is something I was
> desiring recently, a generator to open, unpickle, repickle and close a
> file:
> 
> def pickled_file(name):
>      f = open(name, 'r')
>      l yield pickle.load(f)
>      f.close()
>      f = open(name, 'w')
>      pickle.dump(l, f)
>      f.close()

I believe with PEP 288, this would look something like:

def pickled_file(name):
    self = mygen.get_instance()
    f = open(name, 'r')
    yield pickle.load(f)
    f.close()
    f = open(name, 'w')
    pickle.dump(self.l, f)
    f.close()

> This function would be used like this:
> 
> for l in pickled_file('greetings.pickle'):
>      l.append('hello')
>      l.append('howdy')
>      continue l
> 

And this would be written something like:

gen = pickled_file('greetings.pickle')
for l in gen:
    l.append('hello')
    l.append('howdy')
    gen.l = l

Personally, I find this use of a generator thoroughly confusing, and I
don't see what you gain from it.  The PEP 288 examples are perhaps
somewhat more convincing though...

Steve

[1] http://www.python.org/peps/pep-0288.html
-- 
You can wordify anything if you just verb it.
        --- Bucky Katt, Get Fuzzy


More information about the Python-Dev mailing list