Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python variable scope in nested functions

I am reading this article about decorator.

At Step 8 , there is a function defined as:

def outer():
    x = 1
    def inner():
       print x # 1
    return inner

and if we run it by:

>>> foo = outer()
>>> foo.func_closure # doctest: +ELLIPSIS

it doesn't print x. According to the explanation :

Everything works according to Python’s scoping rules - x is a local variable in our function outer. When inner prints x at point #1 Python looks for a local variable to inner and not finding it looks in the enclosing scope which is the function outer, finding it there.

But what about things from the point of view of variable lifetime? Our variable x is local to the function outer which means it only exists while the function outer is running. We aren’t able to call inner till after the return of outer so according to our model of how Python works, x shouldn’t exist anymore by the time we call inner and perhaps a runtime error of some kind should occur.

However, I don't really understand what the second paragraph means.

I understand inner() does get the value of x but why it doesn't print x out?

thanks

UPDATE:

Thanks all for the answers. Now I understand the reason. the "return inner" is just a pointer to inner() but it doesn't get executed, that is why inner() doesn't print x as it is not called at all

like image 644
Chung Avatar asked Jun 21 '13 05:06

Chung


People also ask

How do you use variables in Nested Functions in Python?

A function defined inside another function is called a nested function. 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.

What is the scope of a nested function?

The scope of a nested function is inside the enclosing function, i.e. inside one of the constituent blocks of that function, which means that it is invisible outside that block and also outside the enclosing function. A nested function can access other local functions, variables, constants, types, classes, etc.

Can a nested function access outer variable?

Nested functionsIt can access the outer variables and so can return the full name.

Can I access variable inside function Python?

In Python and most programming languages, variables declared outside a function are known as global variables. You can access such variables inside and outside of a function, as they have global scope.


1 Answers

I understand inner() does get the value of x but why it doesn't print x out?

It doesn't print out anything because you've not called the inner function yet.

>>> def outer():
        x = 1
        def inner():
               print x # 1
        return inner
...     
>>> func = outer()  
>>> func            
<function inner at 0xb61e280c>
>>> func()
1

This is called a closure, i.e even though the outer function is not in stack(finished executing) anymore but still the inner function that was returned from it remembers it's state.(i.e value of x)

>>> def outer():
            x = 1
            y = 2
            def inner():
                    z=3
                    print x
            return inner
...     
>>> func = outer()
>>> func.func_code.co_freevars  #returns the variables that were used in closure
('x',)

From the source code on how python decides it's a closure or not:

   459    if len(code.co_freevars) == 0:
   460        closure = NULL
   461    else:
   462        len(closure) == len(code.co_freevars)

In py3.x you can also modify the value of x using nonlocal statement inside inner function.

>>> def outer():
        x = 1
        def inner():
           nonlocal x
           x += 1
           print (x)
        return inner
...     
>>> func = outer()
>>> func()
2
>>> func()
3
>>> func()
4
like image 117
Ashwini Chaudhary Avatar answered Sep 21 '22 23:09

Ashwini Chaudhary