What are python closures realy like?

Klaas mike.klaas at gmail.com
Fri Dec 1 17:00:40 EST 2006


Karl Kofnarson wrote:
> Hi,
> while writing my last program I came upon the problem
> of accessing a common local variable by a bunch of
> functions.
> I wanted to have a function which would, depending on
> some argument, return other functions all having access to
> the same variable. An OO approach would do but why not
> try out closures...
> So here is a simplified example of the idea:
> def fun_basket(f):
>     common_var = [0]
>     def f1():
>         print common_var[0]
>         common_var[0]=1
>     def f2():
>         print common_var[0]
>         common_var[0]=2
>     if f == 1:
>         return f1
>     if f == 2:
>         return f2
> If you call f1 and f2 from the inside of fun_basket, they
> behave as expected, so common_var[0] is modified by
> whatever function operates on it.
> However, calling f1=fun_basket(1); f2 = fun_basket(2) and
> then f1(); f2() returns 0 and 0. It is not the way one would
> expect closures to work, knowing e.g. Lisp make-counter.
> Any ideas what's going on behind the scene?

Python can be read quite literally.  "common_var" is a local variable
to fun_basket, hence it independent among invokations of fun_basket.
"def" is a statement that creates a function when it is executed.  If
you execute the same def statement twice, two different functions are
created.  Running fun_basket twice creates four closures, and the first
two have no relation to the second two.  The two sets close over
different cell variables.

If you want to share data between function invokation, you need an
object which persists between calls. You can use a global variable, or
a default argument.  But since the value is shared everytime the
function is called, I don't see the value in using a closure.  I don't
know lisp very well, but in my mind the whole point of closures is that
you can reference a different unique cell each time.

-MIke




More information about the Python-list mailing list