views:

43

answers:

2

As I am studying decorators, I noticed something strange :

def f():
...     msg='aa'
...     def a():
...             print msg
...     msg='bb'
...     def b():
...             print msg
...     return a,b
... 
>>> a,b = f()
>>> a()
bb
>>> b()
bb
>>> 

Why a() returns 'bb' and not 'aa' ??

+3  A: 

Because a and b have the same outer scope, in which msg is bound to 'bb'. Put them in separate functions if you want them to have separate scopes.

Ignacio Vazquez-Abrams
yes but when a() is defined, msg = 'aa' then.Does that means functions are really defined at the end of the parent function ?
Eric
The scope is bound to the function when the function is defined. But the name *within* the scope is rebound to a different string.
Ignacio Vazquez-Abrams
@Eric: The variable `msg` is not defined as a constant "aa". The variable survives in the local scope of `f`, and the inner functions `a`/`b` have access to that scope at any later time. As you overwrite the value of `msg` immediately, i.e. before calling `a` or `b`, they will read the new value.
AndiDog
Yes, I believed it was like ADA language template mechanism. But, yes, that sound finally very logical. Thank you all
Eric
+1  A: 

Both a and b have read access to the outer scope (the local scope of f). As you overwrite the value of msg, the later call to a/b will read the new value.

AndiDog
OK, I believed that It was like ADA language template mechanism, in fact a/b are using the still living msg variable in its scope, so having the value 'bb' at the time a/b are executed.
Eric