lambda closure question

jfj jfj at freemail.gr
Sat Feb 19 17:15:55 EST 2005


Carl Banks wrote:

> jfj wrote:
> 
>>Carl Banks wrote:
>>
>>>Ted Lilley wrote:
>>>
>>>>Unfortunately, it doesn't work.  It seems the closure keeps track
> of
> 
>>>>the variable fed to it dynamically - if the variable changes after
>>>
>>> [...]
>>>
>>>>At least, that's the explanation I'm deducing from this behavior.
>>>
>>>
>>>And that's the correct explanation, chief.
>>
>>>It is intended that way.  As an example of why that is: consider a
>>>nested function called "printvars()" that you could insert i
> 
> various
> 
>>>places within a function to print out the value of some local
> variable.
> 
>>> If you did that, you wouldn't want printvars to print the values
> at
> 
>>>the time it was bound, would you?
>>
>>Allow me to disagree (and start a new "confused with closures"
> thread:)
> 
>>We know that python does not have references to variables. To some
>>newcomers this may seem annoying but eventually they understand the
>>pythonic way and they do without them. But in the case of closures
>>python supports references!
> 
> 
> That's right.  It's called Practicality beats purity.
> 

Yes, but according to the python philosophy one could pass locals()
to the nested function and grab the values from there. Seems practical
for the rareness of this...

>  My experience bears this out: I find that about half the nested
> functions I use are to reference an outer scope, half I return as a
> closure.  Only once or twice did I try to use a nested function inside
> the defining function.  I would guess this is more or less typical of
> how nested functions are used.  If so, it was the right decision.
> 

The question is how many of the nested functions you use take advantage
of the fact that the deref'd variable is a *reference to a variable* and
not a *constant* (different constant for each definition of the nested
function of course).
Or, IOW, it seems very reasonable that if somebody wants to write the
"printvars()" function, he could simply pass locals().

I would accept this being the right decision if there was a statement
like "global var", called "deref var" with which nested funcs could
modify those variables.  Then we could say:

#############
def foo():
     def f1(y):
         deref x
         x = y
     def f2():
         print x
     x=11
     return f1, f2
####################
But one should go with OOP in that case instead.

Ogligatory Python 3000 suggestion:
I hope in python 3000, we'll get rid of CellObjects and insert
freevars at the consts of the function object at MAKE_CLOSURE.


jfj




More information about the Python-list mailing list