Re: Problem with Lexical Scope



jslowery@xxxxxxxxx wrote:
I am not completely knowledgable about the status of lexical scoping in
Python, but it was my understanding that this was added in a long time
ago around python2.1-python2.2

I am using python2.4 and the following code throws a "status variable"
not found in the inner-most function, even when I try to "global" it.

def collect(fields, reducer):
    def rule(record):
        status = True
        def _(x, y):
            cstat = reducer(x, y)
            if status and not cstat:
                status = False
            return y
        return reduce(_, [record[field] for field in fields])
    return rule

What gives?

What's happening is that the interpreter, when it compiles the inner function _(), sees an assignment to status and so assumes it is local to the _() function. Consequently, since you reference it inside _() before assignment you get (I presume) an exception reporting an unbound local variable.

The scoping rules do work when you obey them:

 >>> def f1(a, b):
 ...   s = a+b
 ...   def _(x):
 ...     return s+x
 ...   return _
 ...
 >>> func = f1(12, 13)
 >>> func(10)
35
 >>>

Here the nested lexical scopes rule isn't that helpful given the overriding nature of assignment within an inner scope. Using global will simply put the status variable at *module* scope, which also isn't what you want.

regards
 Steve
--
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/

.



Relevant Pages

  • Re: Nested scopes, and augmented assignment
    ... nested scope, on variables from the outer scope: ... def f: ... leftside of an assignment should depend on whether the name ... is the target or prefix for the target. ...
    (comp.lang.python)
  • Re: Nested scopes, and augmented assignment
    ... AP> rebind variables that are out of the local scope. ... AP> side of an assignment is a simple name it will only search in the ... AP> rebinding a name in an intermediate scope. ... AP> def f: ...
    (comp.lang.python)
  • RE: updating a variable / scope problem
    ... > def f: ... > UnboundLocalError: local variable 'c' referenced before assignment ... > So which scope is c local to in this example? ... since it involves a binding (assignment). ...
    (comp.lang.python)
  • Re: Why no lexical scoping for a method within a class?
    ... You're mistaking lexical scoping for object attribute access. ... def message: ... The reason is that the class scope is deliberately left out of the nested ...
    (comp.lang.python)
  • Re: How to access to local variables in enclosing scopes?
    ... There is a another reason why class and def create fresh scopes, ... One of the benefits of Ruby is its lack of verbosity: ... def foo ... Now consider what would happen if 'def' didn't start a new scope. ...
    (comp.lang.ruby)