Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why nested functions can access variables from outer functions, but are not allowed to modify them [duplicate]

Tags:

python

scope

In the 2nd case below, Python tries to look for a local variable. When it doesn't find one, why can't it look in the outer scope like it does for the 1st case?

This looks for x in the local scope, then outer scope:

def f1():
    x = 5
    def f2():
         print x

This gives local variable 'x' referenced before assignment error:

def f1():
    x = 5
    def f2():
        x+=1

I am not allowed to modify the signature of function f2() so I can not pass and return values of x. However, I do need a way to modify x. Is there a way to explicitly tell Python to look for a variable name in the outer scope (something similar to the global keyword)?

Python version: 2.7

like image 519
Dhara Avatar asked Aug 16 '12 12:08

Dhara


People also ask

Can a nested function access outer variable?

Python Inner Functions or Nested Functions can access the variables of the outer function as well as the global variables.

Can you call a nested function outside a function?

Nested function is private to containing function Only the containing function can access the nested function. We cannot access it anywhere outside the function. This is because the inner function is defined in the scope of the outer function (or containing function).

Which variables Cannot be accessed outside the function?

Variables declared inside any function with var keyword are called local variables. Local variables cannot be accessed or modified outside the function declaration.

How do you use variables in nested functions?

Nested functions can access variables of the enclosing scope. In Python, these non-local variables are read-only by default and we must declare them explicitly as non-local (using nonlocal keyword) in order to modify them. Following is an example of a nested function accessing a non-local variable.


2 Answers

In Python 3.x this is possible:

def f1():
        x = 5
        def f2():
                nonlocal x
                x+=1
        return f2

The problem and a solution to it, for Python 2.x as well, are given in this post. Additionally, please read PEP 3104 for more information on this subject.

like image 167
hochl Avatar answered Oct 20 '22 23:10

hochl


def f1():
    x = { 'value': 5 }
    def f2():
        x['value'] += 1

Workaround is to use a mutable object and update members of that object. Name binding is tricky in Python, sometimes.

like image 78
Tom Whittock Avatar answered Oct 21 '22 00:10

Tom Whittock