Accessing variables defined in enclosing scope

Brad Solomon :

From the Google Style Guide on lexical scoping:

A nested Python function can refer to variables defined in enclosing functions, but can not assign to them.

Both of these seem to check out at first:

# Reference
def toplevel():
    a = 5
    def nested():
        print(a + 2)
    nested()
    return a
toplevel()
7
Out[]: 5

# Assignment
def toplevel():
    a = 5
    def nested():
        a = 7 # a is still 5, can't modify enclosing scope variable
    nested()
    return a
toplevel()
Out[]: 5

So why, then, does a combination of both reference and assignment in the nested function lead to an exception?

# Reference and assignment
def toplevel():
    a = 5
    def nested():
        print(a + 2)
        a = 7
    nested()
    return a
toplevel()
# UnboundLocalError: local variable 'a' referenced before assignment
Mohd :

In first case, you are referring to a nonlocal variable which is ok because there is no local variable called a.

def toplevel():
    a = 5
    def nested():
        print(a + 2) # theres no local variable a so it prints the nonlocal one
    nested()
    return a

In the second case, you create a local variable a which is also fine (local a will be different than the nonlocal one thats why the original a wasn't changed).

def toplevel():
    a = 5 
    def nested():
        a = 7 # create a local variable called a which is different than the nonlocal one
        print(a) # prints 7
    nested()
    print(a) # prints 5
    return a

In the third case, you create a local variable but you have print(a+2) before that and that is why the exception is raised. Because print(a+2) will refer to the local variable a which was created after that line.

def toplevel():
    a = 5
    def nested():
        print(a + 2) # tries to print local variable a but its created after this line so exception is raised
        a = 7
    nested()
    return a
toplevel()

To achieve what you want, you need to use nonlocal a inside your inner function:

def toplevel():
    a = 5
    def nested():
        nonlocal a
        print(a + 2)
        a = 7
    nested()
    return a

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Local variable i defined in an enclosing scope must be final or effectively final

Local variable log defined in an enclosing scope must be final or effectively final

Local variable defined in an enclosing scope must be final or effectively final

Accessing JS scope elements/variables with Protractor

Python enclosing scope variables with lambda function

Enclosing functions scope search?

(Typos in Oracle tutorial?) Accessing local variables of the enclosing scope from a lambda expression

Accessing variables out of scope

This undefined in fat arrow function but is defined in the enclosing scope

variables defined in a scope v.s. namespace variables injected in that scope

Return the enclosing scope variables in Python

Modifying array defined in enclosing scope in lambda

Access to Variables in Enclosing Scope for Simple Namespace

Local variable list defined in an enclosing scope must be final or effectively final

Accessing variables in an enclosing scope(not global) hidden by local declaration in C++?

Are requires expressions allowed to "capture" variables of the enclosing scope?

acessing variables inside an enclosing scope, specifically BlahListeners

AngularJS: accessing scope variables in $routeProvider

Accessing defined session / variables inside razor view

Angular ng-bind not accessing scope variables

Node array of function using variables from enclosing scope

Lambda Expression Local variable text defined in an enclosing scope JavaFx

Usage of enclosing scope in C

Getting local variable defined in the enclosing scope must be final or effective final

Scope of locally defined variables in vue

Getting "NameError: name not defined" when accessing previously defined variables

Accessing variables in local scope and adding them to global scope in Julia

Local variable collect defined in an enclosing scope must be final or effectively final

Accessing variables in the local scope of a python decorator