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
You are not calling
inner
. You have calledouter
, which returnsinner
, but without calling it. If you want to callinner
, dofoo()
(since you assinged the result ofouter()
to the namefoo
).The paragraph you quoted is sort of tangential to this issue. You say you already understand why
inner
gets the value ofx
, which is what that paragraph is explaining. Basically, if a local variable is used in a nested function, and that nested function is returned, the value of the variable is stored along with the returned function, even if the scope where that variable was defined in no longer active. Normallyx
would be gone afterouter
finished, becausex
is just local toouter
. Butouter
returnsinner
, which still needs access tox
. Sox
gets wrapped up into what's called a closure, so it can still be accessed byinner
later on.It doesn't print out anything because you've not called the inner function yet.
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
)From the source code on how python decides it's a closure or not:
In py3.x you can also modify the value of
x
usingnonlocal
statement inside inner function.