mdw at distorted.org.uk
Sat Nov 13 23:22:00 CET 2010
Arnaud Delobelle <arnodel at gmail.com> writes:
> mdw at distorted.org.uk (Mark Wooding) writes:
> > Assignment /never/ binds. There is syntactic confusion here too,
> > since Python interprets a simple assignment in a function body -- in
> > the absence of a declaration such as `global' to the contrary -- as
> > indicating that the variable in question should be bound to a fresh
> > variable on entry to the function. But assignment itself doesn't
> > perform binding. (This is a persistent error in the Python community;
> > or, less charitably, the Python community gratuitously uses the word
> > in a different sense from the wider programming-language-theory
> > community. See Lisp literature passim, for example.)
> > There's a two step mapping: names -> storage locations -> values.
> > Binding affects the left hand part of the mapping; assignment affects
> > the right hand part.
> I'm not sure the notion of "storage location" is useful in Python.
> I think I understand Python programs correctly using only the notions
> of "name" and "value" (or object).
Challenge: explain the following code using only those concepts.
l = 
for i in xrange(10):
(lambda j: l.append((lambda: i, lambda: j)))(i)
print [(f(), g()) for f, g in l]
I explain this as follows.
* Python's `for' loop works by assignment. The name `i' remains bound
to the same storage location throughout; this binding is established
on entry to the function. Since `i' is not rebound in any function
lexically enclosed in `foo', every occurrence of `lambda: i' refers
to this same storage location. At the end of the loop, this storage
location contains the value 9.
* The name `j' is rebound repeatedly: in each iteration of the `for'
loop, the function `lambda j: ...' is invoked, binding `j' to a
fresh storage location into which the value of `i' at the time is
stored. Since the function `lambda: j' is lexically enclosed within
this function, the name `j' refers to a different storage location
in each of these functions, these storage locations are initialized
with distinct values 0 up to 9, and they are never changed.
* Therefore each `lambda: i' function, when called after the loop,
outputs the same value 9; and each `lambda: j' function, when called
after the loop, outputs a distinct value.
More information about the Python-list