Python variable scope in nested functions

I am reading this article about a decorator.

In Step 8, there is a function defined as:

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

and if we run it:

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

it does not print x. According to the explanation:

Everything works according to the rules of the review. Pythons - x is a local variable in our external function. When the inner print of x at point # 1, Python searches for a local variable in the inside and does not find it in the scope, which is an external function, finding it there.

But what about things in terms of variable lifetime? our variable x is local to the external function, which means that it exists only and the external function works. We can name internal before after returning external, so according to our model of how Python works, x should not exist anymore by the time we call internal and, possibly, a runtime error should occur.

However, I do not quite understand what the second paragraph means.

I understand that inner () really gets the value of x, but why doesn't it print x out?

thanks

UPDATE

Thanks everyone for the answers. Now I understand the reason. " return inner " is a pointer for internal (), but it fails, so inner () does not print x, since it is not called at all

+6
source share
2 answers

You do not call inner . You called outer , which returns inner , but not calling it. If you want to call inner , do foo() (since you appreciated the result of outer() on the name foo ).

The paragraph you cited is tangential to this problem. You say you already understand why inner gets the value x , which explains this paragraph. In principle, if a local variable is used in a nested function and a nested function is returned, the value of the variable is saved along with the returned function, even if the region in which this variable was defined is no longer active. Usually x will disappear after outer complete, because x is only local to outer . But outer returns inner , which still needs access to x . So x ends up in what is called a closure, so you can still access it inner later.

+2
source

I understand that inner () really gets the value of x, but why doesn't it print x out?

It does not print anything because you have not yet called an internal function.

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

This is called closure , i.e. although the external function is no longer on the stack (ready-made execution), but still the internal function that was returned from it remembers its state (i.e. the 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 to close it 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 change the value of x using the nonlocal instruction inside the internal function.

 >>> def outer(): x = 1 def inner(): nonlocal x x += 1 print (x) return inner ... >>> func = outer() >>> func() 2 >>> func() 3 >>> func() 4 
+7
source

Source: https://habr.com/ru/post/947807/


All Articles