why is this not working? (nested scope question)

B

biner.sebastien

I have a problem understanding the scope of variable in nested
function. I think I got it nailed to the following example copied from
Learning Python 2nd edition page 205. Here is the code.

def f1() :
x=88
f2()
def f2() :
print 'x=',x
f1()

that returns an error saying that "NameError: global name 'x' is not
defined". I expected f2 to "see" the value of x defined in f1 since it
is nested at runtime. My reading of the book comforted me in this.

What am I missing? Shouldn't the E of the LEGB rule take care of that.
BTW, I am running this on python 2.3.

Thanks.

Sébastien.
 
P

Peter Otten

I have a problem understanding the scope of variable in nested
function. I think I got it nailed to the following example copied from
Learning Python 2nd edition page 205. Here is the code.

def f1() :
x=88
f2()
def f2() :
print 'x=',x
f1()

that returns an error saying that "NameError: global name 'x' is not
defined". I expected f2 to "see" the value of x defined in f1 since it
is nested at runtime. My reading of the book comforted me in this.

What am I missing? Shouldn't the E of the LEGB rule take care of that.
BTW, I am running this on python 2.3.

For f1 to be seen as the enclosing scope of f2 f2 has to be /defined/ in f1:
.... x = 88
.... def f2():
.... print "x =", x
.... f2()
....x = 88

Just /calling/ a function inside another does not give the inner one access
to variables that are visible in the outer.

Peter
 
S

Sybren Stuvel

(e-mail address removed) enlightened us with:
I have a problem understanding the scope of variable in nested
function. I think I got it nailed to the following example copied from
Learning Python 2nd edition page 205. Here is the code.

def f1() :
x=88
f2()

Here x is defined in the function-local scope of f1.
def f2() :
print 'x=',x

Here x is used from the function-local scope of f2.
f1()

that returns an error saying that "NameError: global name 'x' is not
defined". I expected f2 to "see" the value of x defined in f1 since
it is nested at runtime. My reading of the book comforted me in
this.

x is local in f1, and thus not in f2. Calling order has nothing to do
with it - it's a matter of definition. If f2 were to be defined
_inside_ f1, after x had gotten its value, you'd be right:

def f1():
x = 88

def f2():
print 'x = %i' % x

f2()

This would work as you'd expect.

Sybren
 
B

bryanjugglercryptographer

def f1() :
x=88
f2()
def f2() :
print 'x=',x
f1()

that returns an error saying that "NameError: global name 'x' is not
defined". I expected f2 to "see" the value of x defined in f1 since it
is nested at runtime.

Ah, no, Python uses "static scoping". Google the term for more.
 
T

Tim Chase

I have a problem understanding the scope of variable in nested
function. I think I got it nailed to the following example copied from
Learning Python 2nd edition page 205. Here is the code.

def f1() :
x=88
f2()
def f2() :
print 'x=',x
f1()

that returns an error saying that "NameError: global name 'x' is not
defined". I expected f2 to "see" the value of x defined in f1 since it
is nested at runtime. My reading of the book comforted me in this.

What am I missing? Shouldn't the E of the LEGB rule take care of that.

There's a subtle difference between what you have:
.... x=88
.... f2()
[traceback]

and
.... x = 88
.... def f2():
.... print 'x =',x
.... f2()
....x = 88

The E in LEGB, as far as I understand it, involves to functions
whose *definitions* are nested within another function...not
those functions *called* within another function. Craziness
ensues with the next example:
.... x = 99
.... def f2():
.... print 'x =',x
.... x = 77
.... f2()
....x = 77


It makes sense...you just have to understand what it's doing. :)

-tkc
 
B

biner.sebastien

Thanks for the answers.

I do understand (and verified) that if I define f2 within f1, it works
as expected. But in the "learning pyton 2nd edition" at page 205 it is
said that "Programs are much simpler if you do not nest defs within
defs" (juste before the code mentioned in my initial message).

In a way, I though the local variables of f1 would in a way add to the
global variable of f2 (because f1 called f2) and that f2 would look in
the global variables when it could not find a variable locally
(following the LEGB rule).

Still the code I put is presented in the book and it does not work for
me. I googled for errata regarding that code but did not find any.

Sébastien.
 
J

John Salerno

I do understand (and verified) that if I define f2 within f1, it works
as expected. But in the "learning pyton 2nd edition" at page 205 it is
said that "Programs are much simpler if you do not nest defs within
defs" (juste before the code mentioned in my initial message).

Actually, the code in the book is:

def f1():
x = 88
f2(x)

def f2(x):
print x

f1()

which makes all the difference in the world. Not to mention that this
particular section of the book is giving an example of how to write the
code *without* using nested functions.
 
B

biner.sebastien

Actually, the code in the book is:

def f1():
x = 88
f2(x)

def f2(x):
print x

f1()

which makes all the difference in the world. Not to mention that this
particular section of the book is giving an example of how to write the
code *without* using nested functions.

Ouch! You got me there, I did not copy the code properly. Now I feel
stupid. Thanks for the enlightment.

I think I am starting to get it.

Sébastien.
 
J

John Salerno

Ouch! You got me there, I did not copy the code properly. Now I feel
stupid. Thanks for the enlightment.

I think I am starting to get it.

P.S. The point of the example was to show how nesting isn't necessary
much of the time. The authors wanted to show that it is okay to write a
call to f2 before f2 is even defined, as long as f2 is defined before
that call is actually executed, i.e. when f1() is called. Keeping the
two functions separate is cleaner than nesting, and passing parameters
is how you get around the local scope issue.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top