Lambda forms and scoping
R. David Murray
rdmurray at bitdance.com
Mon Mar 23 10:11:15 EDT 2009
"Gabriel Genellina" <gagsl-py2 at yahoo.com.ar> wrote:
> > 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's true in Python 2.x, but 3.x has the "nonlocal" keyword - so you can
> modify variables in outer scopes too:
>
> p3> z = 1
> p3> def o():
> ... z = 2
> ... def i():
> ... nonlocal z
> ... print("z in i:", z)
> ... z = 5
> ... print("z in o:", z)
> ... i()
> ... print("z in o:", z)
> ... z=3
> ... print("z in o at exit:", z)
> ... return i
> ...
> p3> i=o()
> z in o: 2
> z in i: 2
> z in o: 5
> z in o at exit: 3
> p3> z
> 1
> p3> i()
> z in i: 3
> p3> i()
> z in i: 5
>
> (Anyway I think the inability to "modify" a variable doesn't invalidate
> the "closure" concept...)
Invalidate, no, but it does mean that the word meant something slightly
different to a Python 2.x programmer than to, say, a Scheme programmer.
We could say that a Python 2.x closure is a "read-only closure".
But now with Python 3.x we can really have fun (thank you for that info):
>>> def g():
... def a(x):
... nonlocal z
... z = z + x
... def b(x):
... nonlocal z
... z = z - x
... def p():
... print(z)
... z = 1
... return a, b, p
...
>>> add, sub, pr = g()
>>> pr()
1
>>> add(10)
>>> pr()
11
>>> sub(5)
>>> pr()
6
So, as the wikipedia article says, we could, if we wanted to, use python 3
closures to reimplement objects, in a very confusing fashion :)
--
R. David Murray http://www.bitdance.com
More information about the Python-list
mailing list