full closures
Luigi Ballabio
ballabio at mac.com
Thu Feb 28 05:02:12 EST 2002
At 03:47 PM 2/27/02 -0800, Andrae Muys wrote:
> > I don't understand closures, but I might try something like:
> >
> > class Counter:
> > def __init__(self):
> > self.count = 0
> > def __int__(self):
> > self.count += 1
> > return self.count
> >
> > counter = Counter()
> > print "the current count is %d" % counter
> >
>
>That works, as does using a generator:
>
>def Counter():
> counter = 0
> while 1:
> print "the current count is %d % counter
> counter += 1
> yield counter - 1 # might as well return it :)
Hi all,
the usual Scheme closure thing, twisted and perverted to have it
work in Python but probably very un-Pythonic because of that, would look like:
>>> def counter(x=0):
... l = [x-1]
... def f(l):
... l[0] += 1
... return l[0]
... return lambda: f(l)
...
>>> c1 = counter()
>>> c2 = counter(5)
>>> c1()
0
>>> c1()
1
>>> c1()
2
>>> c2()
5
>>> c2()
6
Note: the above only works in Python 2.2 (by default) or Python 2.1 (by
importing nested_scope from __future__)
Much of the awkwardness comes from having to store the counter in a list to
have pass-by-reference to f, and from having to define a separate f because
lambda is limited to a single expression. In Scheme, which has different
semantics, this trick is done much more tersely as
(define (counter x)
(let ((y (- x 1)))
(lambda () (set! y (+ y 1)) y)))
which in non-working pseudo-Python syntax for the parens-challenged would be:
def counter(x):
y = x-1
return lambda: y += 1; y
but one can't have everything. It wouldn't be Python if it had Scheme
semantics...
Bye,
Luigi
More information about the Python-list
mailing list