What are python closures realy like?
Paddy
paddy3118 at netscape.net
Wed Dec 6 01:59:29 EST 2006
Karl Kofnarson wrote:
> > Karl,
> >
> > Usually when using this idiom, fun_basket would return a tuple of all of the
> > defined functions, rather than one vs. the other. So in place of:
> >> if f == 1:
> >> return f1
> >> if f == 2:
> >> return f2
> > Just do
> >> return f1, f2
> > (For that matter, the argument f is no longer needed either.)
> >
> > Then your caller will get 2 functions, who share a common var. You don't
> > call fun_basket any more, you've already created your two "closures". Call
> > fun_basket using something like:
> >
> > z1,z2 = fun_basket(None)
> >
> > And then call z1() and z2() at your leisure - they should have the desired
> > behavior.
> >
> > -- Paul
>
> Thanks a lot Paul and for the other answers. The things are now
> clear to me. In fact, in the Lisp example that I mentioned, you
> get a list (or let it be association list) of the internal
> functions. Then you can call them separately and they work as
> you expect but it's due to the fact only that you got them created
> at the same time.
I played around a bit. The following is a 'borg' version in that there
is only one counter shared between all calls of the outer function:
>>> def fun_borg_var(initial_val=0):
... def borg_var_inc(x=1):
... fun_borg_var._n += x
... return fun_borg_var._n
... def borg_var_dec(x=1):
... fun_borg_var._n -= x
... return fun_borg_var._n
... try:
... fun_borg_var._n = fun_borg_var._n
... except:
... fun_borg_var._n = initial_val
... return (borg_var_inc, borg_var_dec)
...
>>> up1, dn1 = fun_borg_var() # get an inc/decrementer
>>> up1(0)
0
>>> up1()
1
>>> up1()
2
>>> dn1()
1
>>> dn1()
0
>>> dn1()
-1
>>> up2, dn2 = fun_borg_var() # get another inc/decrementer
>>> up2(0) # looks like the same _n
-1
>>> up2(3)
2
>>> up1(3)
5
>>>
- Paddy.
More information about the Python-list
mailing list