Is there "let binding" in Python?

Anton Vredegoor anton at vredegoor.doge.nl
Tue Sep 16 18:41:53 EDT 2003


Rob Hunter <rhunter007 at yahoo.com> wrote:

>wrong).  What you're describing is "dynamic
>scoping".  That's where the body of a function
>(or code block in this case) isn't evaluated
>until it is used.  And thus, free variables in
>the body assume whatever values their calling
>environment has.  Dynamic scoping is a bad thing.
> So bad, in fact, that lisp added (at least the
>option of, I think) static scoping, Scheme
>exclusively uses static scoping, and that Python
>corrected their mistake (it used to be
>dynamically scoped).

What's wrong with dynamic scoping? Anyway, Python hasn't corrected
this "mistake", see following code (I vaguely remember *something*
about this was fixed, and while I don't know exactly what it was, I'm
reasonably sure it wasn't what you write about above, since that still
functions the way you think is bad)

import sys

def test():
    L =[]
    for i in range(10):
        f = lambda : sys.stdout.write("%s" %i)
        g = lambda i=i : sys.stdout.write("%s" %i)
        L.append((f,g))
    for x,y in L:
        x()
        y()
    print

if __name__=='__main__':
    test()

# output : 90919293949596979899

>But anyway, from my tests, and from what I've
>read, Python has static scoping, but what
>assignment allows you to do is violate, in a way,
>this static scoping, which is what we see here.

Probably assignment *enables* static scoping if following this line of
reasoning, since if there's no statement "global i" in a function,
assigning "i" results in binding a local name "i".

Binding "i" in the test function name space to "i" in the name space
of the lambda function gives the behavior you want. If no binding in
the lambda name space is made, the "i" in the enclosing name space is
used, which is bound to the value "9" by the time function x is
called.

Anton





More information about the Python-list mailing list