Function returns a function

Paul Rubin http
Wed Sep 7 00:29:20 EDT 2005


Aldo Cortesi <aldo at nullcube.com> writes:
> The lexical scope within which a function is declared is
> made available to the function when it is run. This is done
> by storing the values of free variables within the declared
> function in the func_closure attribute of the created
> function object.

Actually not quite right:

   a = []
   for i in range(5):
      a.append(lambda: i)   # i is free in the lambda
   print [f() for f in a]

prints [4,4,4,4,4] instead of [0,1,2,3,4].  The value of i has not
been copied into the closure.  Rather, the closure has a cell bound to
the same place that i is bound.  So:

   for i in range(5):
      def f():
         j = i   # bind a new variable "j" and assign the value from i
         return lambda: j  # j is free and its value doesn't change
      a.append(f())
   print [f() for f in a]

prints [0,1,2,3,4].  There's a Pythonic idiom using default args:

   a = []
   for i in range(5):
      a.append(lambda i=i: i)   # the "inner" i is free in the lambda
   print [f() for f in a]
   
Closures like may look a little surprising in Python but they're a
standard technique in Scheme.  The classic textbook "Structure and
Interpretation of Computer Programming" explains it all.  Full text is
online at:

   http://mitpress.mit.edu/sicp/



More information about the Python-list mailing list