"Gabriel Genellina" <gagsl-...@yahoo.com.ar> wrote: > En Fri, 20 Mar 2009 23:16:00 -0300, alex goretoy > <aleksandr.gore...@gmail.com> escribió: > > > i looks at lambdas as unbound functions(or super function), in the case > > above we create the functions in a list places it in memory unboud, once > > binding a call to the memory address space it returns the value > > > > it is basically same as doing this: > > def f(): > > print "f" > > > > a=f #unbound function, same as rename function > > a() #bind call to address space > > Mmm, I don't quite understand what you said. lambda creates functions that > aren't different than functions created by def: apart from the name, > they're really the same thing.
Oh, good, I'm not the only one for whom the above didn't make sense :) I feel a little less dense now. > And if you imply that *where* you call a function does matter, it does > not. A function carries its own local namespace, its own closure, and its > global namespace. At call time, no additional "binding" is done (except > parameters -> arguments). > > (and the address space is always the one of the running process) I poked around in the API docs and experimented with func_closure and related attributes, and after bending my brain for a while I think I understand this. The actual implementation of the closure is a single list of 'cell' objects which represent namespace slots in the nested scopes in which the closed-over function is defined. But the fact that it is a single list is an implementation detail, and the implementation is in fact carefully designed so that conceptually we can think of the closure as giving the function access to those nested-scope namespaces in almost(*) the same sense that it has a reference to the global and local namespaces. That is, if what a name in _any_ of those namespaces points to is changed, then the closed-over function sees those changes. In this way, we understand the original example: when defining a lambda having a 'free variable' (that is, one not defined in either the local or global scope) that was a name in the surrounding function's local namespace, the lambda is going to see any changes made by the surrounding function with regards to what that name points to. Thus, the final value that the lambda uses is whatever the final value of the for loop variable was when the surrounding function finished executing. However, I think that a Python closure is not quite the same thing as a 'computer science' closure, for the same reason that people coming from a language with variables-and-values as opposed to namespaces get confused when dealing with Python function call semantics. Consider: http://en.wikipedia.org/wiki/Closure_(computer_science) That says that a closure can be used to provide a function with a private set of variables that persist from one invocation to the next, so that a value established in one call can be accessed in the next. The last part of that sentence is not true in Python, since any assignment inside a function affects only the local (per-invocation) namespace or (given a global statement) the global namespace. A function cannot change the thing pointed to by a name in the closure. Only the outer function, for whom that name is in its local namespace, can do that. (*) That last sentence in the previous paragraph is why I said '_almost_ the same sense' earlier: a function can modify what names point to in its local and global namespaces, but cannot modify what names point to in the closure namespace. Of course, we can produce the same _effect_ as a computer science closure in Python by using mutable objects...which is exactly parallel to the difference between passing mutable or immutable objects in a function call. -- R. David Murray http://www.bitdance.com -- http://mail.python.org/mailman/listinfo/python-list