Re: Confused by Python and nested scoping (2.4.3)
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)
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)
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)
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)
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)
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)
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)
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)
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