yet another generator implementation (was Re: how to write function that returns function)

George Demmy gdemmy at layton-graphics.com
Thu May 16 08:07:11 EDT 2002


David Eppstein <eppstein at ics.uci.edu> writes:

> In article <wusn4t46fx.fsf_-_ at hades.layton-graphics.com>,
>  George Demmy <gdemmy at layton-graphics.com> wrote:
> 
> > CL:
> > 
> > (defun foo (n) #'(lambda () (incf n)))
> > 
> > Python:
> > 
> > def foo(n=0):
> >   class bar:
> >     def __init__(self):
> >       self.n = n
> >     def next(self):
> >       self.n += 1
> >       return self.n
> >   return bar().next
> > 
> > f = foo()
> > print f(),f(),f()
> > -> 2 3 4
> > g = foo(1)
> > -> 3 4 5
> 
> You seem to have an off by one error on your output:
> I get 1 2 3 and 2 3 4

Erp. You found a random bug in my python interpreter... namely the one
in my head. I should have run the code through a more reliable one
before posting, eh?

> 
> Anyway, as long as you're going to do that, why not:
> 
> from __future__ import generators
> 
> def foo(n=0):
>     def bar(n=n):
>         while 1:
>             n += 1
>             yield n
>     return bar().next
> 

I wouldn't deny that your example is of greater Pythonic virtue! :)

> [ from earlier message by same author: ]
> > I don't think that the "Guido implementation" of Python allows the
> > capture of state in closures the same way that you can in Scheme and
> > CL, though you can fake it very easily, as above. 
> 
> I think the key difference is that Python's closures only give you read 
> access to the variables.  If you want write access you have to 
> encapsulate them in something else, like a list:
> 
> def foo(n=0):
>     n=[n]
>     def bar():
>         n[0] += 1
>         return n[0]
>     return bar

That is an interesting insight. I guess that's what the class in the
other example is doing... providing encapsulation. The list is
certainly concise!

Kindest regards,

G




More information about the Python-list mailing list