strange behavor....

Arnaud Delobelle arnodel at gmail.com
Sun Nov 14 00:14:22 CET 2010


mdw at distorted.org.uk (Mark Wooding) writes:

> Arnaud Delobelle <arnodel at gmail.com> writes:

>> 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.
>
>         def foo():
>           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.

I don't need "storage locations".  All occurences of the name "i" in the
code above belong the the namespace local to the function "foo".

>   * 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.

I don't need "storage locations" to explain this.  At each iteration a
new lambda function (with a new local namespace) is created and the name
"j" belongs to the namespace which is local to the lambda being created.
Upon call of the lambda, "j" is bound to the current value of "i".

So at each iteration, assignment to "j" is performed in a different
namespace.

You can argue that I use the notion of "namespace" to explain what you
do with "storage locations".  However, even with the notion of storage
location, you *still* need the notion of namespace to understand Python
(see the "lexically enclosed within this function" above).  So I still
maintain that "storage location" is a superfluous notion in Python.

To put it another way, when you say:

    Two occurences of the name "a" are bound to the same storage
    location

I say:

    Two occurences of the name "a" belong to the same namespace

These are equivalent models (in the sense that they will interpret
Python code in the same way), but in order to find out whether two
occurences of a name are bound to the same storage location, you need to
check whether the names belong to the same namespace!

-- 
Arnaud



More information about the Python-list mailing list