How can I do this (from Perl) in Python? (closures)
Nick Craig-Wood
nick at craig-wood.com
Thu Dec 4 07:30:47 EST 2008
Duncan Booth <duncan.booth at invalid.invalid> wrote:
> excord80 at gmail.com wrote:
>
> > I just came across http://www.perl.com/pub/a/2002/05/29/closure.html
> > and wanted to try the "canonical example of closures" in Python. I
> > came up with the following, but it fails:
> >
> > def make_counter(start_num):
> > start = start_num
> > def counter():
> > start += 1
> > return counter
>
> The other answers you got will work, but here's an alternative to
> consider: you can convert the function into a generator and then just
> move the variable inside.
>
> >>> def make_counter(start_num):
> def counter():
> start = start_num
> while 1:
> yield start
> start += 1
> return counter().next
Interesting...
You can also write it without nested functions / closures
def counter(x):
while 1:
yield x
x += 1
def make_counter(start_num):
return counter(start_num).next
I expect the machinery is similar between generators and closures, but
with generators it is a lot more obvious exactly which version of
which variable you are using!
In fact you can always do what you can do with a closure with the
above technique I think...
def make_closure(*args, **kwargs):
# initialisation to local vars
def closure():
# stuff, being careful with nonlocal args & kwargs
return result
vs
def closure(*args, **kwargs):
# initialisation to local vars
while 1:
# normal stuff using args and kwargs
yield result
def make_closure(*args, **kwargs):
return closure(*args, **kwargs).next
I still prefer doing it explicitly with a class though ;-)
--
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
More information about the Python-list
mailing list