Re: Confused by Python and nested scoping (2.4.3)

2006-04-20 Thread Petr Prikryl
I have added some spaces guessing how the original was formatted.
See the simplified example and the explanation below...

Sean Givan wrote...
 Hi.  I'm new to Python [...] something strange.
 This code:

 def outer():
 val = 10
 def inner():
 print val
 inner()
 outer()

 ..prints out the value '10', which is what I was expecting.

 But this code..
 def outer():
 val = 10
 def inner():
 print val
 val = 20
 inner()
 print val
 outer()

 ..I expected to print '10', then '20', but instead got an error:

print val
 UnboundLocalError: local variable 'val' referenced before assignment.

 I'm thinking this is some bug where the interpreter is getting ahead of
 itself, spotting the 'val = 20' line and warning me about something that
 doesn't need warning.  Or am I doing something wrong?

The simplified example of both cases can be
script a.py
-
val = 10

def myFunction():
print val

myFunction()
-

In this case the val is not defined inside myFunction();
therefore, it is searched in the upper level, above
the function body. Such variable is called free variable.

script b.py
-
val = 10

def myFunction():
print val
val = 20

myFunction()

-

In this case the val is assigned inside the myFunction()
and it is not marked to be global. In this case Python
decides that it will be the local variable (cannot be
free variable anymore). Python insists on fact that
in one block the variable can be or free or locally
bound, but not both. This is decided during the
compilation of the module and it does not depend
on whether val = 20 assignment precedes the print val
command or not. It is decided that it will be local
inside myFunction and then the print wants to use
the variable that was not assingned yet.

pepr

P.S. I have just noticed that Terry Jan Reedy answered
similarly. Never mind... Repeat, repeat, repeat until
you know ;)


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-20 Thread Kent Johnson
Kelvie Wong wrote:
 There are only two scopes in Python -- global scope and function scope.

No, Python has local, nested, global and built-in scope.

Kent
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-20 Thread BartlebyScrivener
 P.S. I have just noticed that Terry Jan Reedy answered
 similarly. Never mind... Repeat, repeat, repeat until
 you know ;)

Yes, and some of us appreciate the extra examples.

rick

-- 
http://mail.python.org/mailman/listinfo/python-list


Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Sean Givan
Hi.  I'm new to Python, and downloaded a Windows copy a little while 
ago.  I was doing some experiments with nested functions, and ran into 
something strange.

This code:

def outer():
val = 10
def inner():
print val
inner()

outer()

..prints out the value '10', which is what I was expecting.

But this code..

def outer():
val = 10
def inner():
print val
val = 20
inner()
print val

outer()

..I expected to print '10', then '20', but instead got an error:

   print val
UnboundLocalError: local variable 'val' referenced before assignment.

I'm thinking this is some bug where the interpreter is getting ahead of 
itself, spotting the 'val = 20' line and warning me about something that 
doesn't need warning.  Or am I doing something wrong?

Thanks,
-Sean Givan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Kelvie Wong
There are only two scopes in Python -- global scope and function scope.

On 4/19/06, Sean Givan [EMAIL PROTECTED] wrote:
 Hi.  I'm new to Python, and downloaded a Windows copy a little while
 ago.  I was doing some experiments with nested functions, and ran into
 something strange.

 This code:

 def outer():
 val = 10
 def inner():
 print val
 inner()

 outer()

 ..prints out the value '10', which is what I was expecting.

 But this code..

 def outer():
 val = 10
 def inner():
 print val
 val = 20
 inner()
 print val

 outer()

 ..I expected to print '10', then '20', but instead got an error:

print val
 UnboundLocalError: local variable 'val' referenced before assignment.

 I'm thinking this is some bug where the interpreter is getting ahead of
 itself, spotting the 'val = 20' line and warning me about something that
 doesn't need warning.  Or am I doing something wrong?

 Thanks,
 -Sean Givan
 --
 http://mail.python.org/mailman/listinfo/python-list



--
Kelvie
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Ben Cartwright
Sean Givan wrote:
 def outer():
   val = 10
   def inner():
   print val
   val = 20
   inner()
   print val

 outer()

 ..I expected to print '10', then '20', but instead got an error:

print val
 UnboundLocalError: local variable 'val' referenced before assignment.

 I'm thinking this is some bug where the interpreter is getting ahead of
 itself, spotting the 'val = 20' line and warning me about something that
 doesn't need warning.  Or am I doing something wrong?


Short answer:  No, it's not a Python bug.  If inner() must modify
variables defined in outer()'s scope, you'll need to use a containing
object.  E.g.:

  class Storage(object):
  pass
  def outer():
  data = Storage()
  data.val = 10
  def inner():
  print data.val
  data.val = 20
  inner()
  print data.val

Long answer:

The interpreter (actually, the bytecode compiler) is indeed looking
ahead.  This is by design, and is why the global keyword exists.  See
http://www.python.org/doc/faq/programming/#what-are-the-rules-for-local-and-global-variables-in-python

Things get more complex than that when nested function scopes are
involved.  But again, the behavior you observed is a design decision,
not a bug.  By BDFL declaration, there is no parentscope keyword
analogous to global.  See PEP 227, specifically the Rebinding names
in enclosing scopes section: http://www.python.org/dev/peps/pep-0227/

Hope that helps,
--Ben

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Schüle Daniel
Sean Givan schrieb:
 Hi.  I'm new to Python

welcome

 ago.  I was doing some experiments with nested functions, and ran into 
 something strange.
 
 This code:
 
 def outer():
 val = 10
 def inner():
 print val
 inner()
 
 outer()
 
 ...prints out the value '10', which is what I was expecting.
 
 But this code..
 
 def outer():
 val = 10
 def inner():
 print val
 val = 20
 inner()
 print val
 
 outer()
 
 ...I expected to print '10', then '20', but instead got an error:
 
   print val
 UnboundLocalError: local variable 'val' referenced before assignment.
 
 I'm thinking this is some bug where the interpreter is getting ahead of 
 itself, spotting the 'val = 20' line and warning me about something that 

just a little carefull thought
if something that basic should really be a bug
how many thousand people would discover it daily?

 doesn't need warning.  Or am I doing something wrong?

yes, you can't modify it
you can do it for global namespace or local
but not inbetween

val = 0
def outer():
val = 10
def inner():
global val
val = 30
inner()
print val
outer()
10  # outer val is not changed
print val   # global is modified
30

hth, Daniel

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Terry Reedy

Sean Givan [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
 Hi.  I'm new to Python, and downloaded a Windows copy a little while
 ago.  I was doing some experiments with nested functions, and ran into
 something strange.
Experiments are good.  Strange can be instructive.
...
 I'm thinking this is some bug
Blaming the interpreter is not so good, but amazingly common among 
newcomers ;-)

 where the interpreter is getting ahead of  itself,
...
  Or am I doing something wrong?

In a sense, you got ahead of yourself.  And the issue has nothing to do 
with nested scopes per se.  When things seem strange, try a simpler 
experiment.
 x=1
 def f():
 print x
 x = 2

 f()
Traceback (most recent call last):
  File pyshell#5, line 1, in -toplevel-
f()
  File pyshell#4, line 2, in f
print x
UnboundLocalError: local variable 'x' referenced before assignment

The compiler compiles functions in two passes: the first to classify names 
as local or global (or nested if relevant, but not really so here), the 
second to generate bytecodes which depend on that classification.

Terry Jan Reedy



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confused by Python and nested scoping (2.4.3)

2006-04-19 Thread Fredrik Lundh
Sean Givan wrote:

 Hi.  I'm new to Python, and downloaded a Windows copy a little while
 ago.  I was doing some experiments with nested functions, and ran into
 something strange.

 This code:

 def outer():
 val = 10
 def inner():
 print val
 inner()

 outer()

 ..prints out the value '10', which is what I was expecting.

 But this code..

 def outer():
 val = 10
 def inner():
 print val
 val = 20
 inner()
 print val

 outer()

 ..I expected to print '10', then '20', but instead got an error:

print val
 UnboundLocalError: local variable 'val' referenced before assignment.

 I'm thinking this is some bug where the interpreter is getting ahead of
 itself, spotting the 'val = 20' line and warning me about something that
 doesn't need warning.  Or am I doing something wrong?

reading the reference documentation may help:

http://docs.python.org/ref/naming.html

If a name binding operation occurs anywhere within a code block,
all uses of the name within the block are treated as references to
the current block.

/F



-- 
http://mail.python.org/mailman/listinfo/python-list