Dumb newbie back in shell

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Tue Dec 11 09:44:18 EST 2007


MartinRinehart at gmail.com a écrit :
<OT>
Martin, would you _please_ learn to quote properly ? top-posting and 
keeping the whole text of the previous posts are two really annoying 
practices. TIA
</OT>

> I'm less confused. If someone can explain the wisdom of this design,
> I'd be grateful.

Since there's no distinct declarations of names, all names are by 
default created in the local namespace when bound in this namespace. 
Else you couldn't shadow global names in a local namespace... OTHO, free 
variables are looked up in all enclosing namespaces, so in a a 
non-nested function, names used but not bound in the local namespace are 
looked up in the global one.

> If someone can explain why the following compiles successfully, I'd be
> even more grateful:
> 
> def get_toks( text ):
>     global line_ptr, last_line
>     while line_ptr < last_line:
>         while char_ptr < len(text[line_ptr]):
>             if matches_EOI():
>                 tokens.append( Token(EOI) )
>             elif matches_EOL():
>                 tokens.append( Token(EOL) )
>                 line_ptr += 1
>                 char_ptr = 0

FWIW, this code is incomplete. Please post the minimal *working* code 
reproducing your problem. Here, I had to define all the missing symbols 
to test your script.

> Shouldn't "char_ptr" be flagged as an error, appearing in line 4
> before being a lhs in the last line?

Note that such errors are raised at runtime, not during compilation 
(FWIW, I wonder why, since the use of the name is detected at 
compilation IIRC).

The error appears as long as line_ptr < last_line before calling the 
function. Now when line_ptr >= last_line, there is no error. So I 
conclude that UnboundLocalErrors are not raised until the offending line 
is actually executed.

Now while I don't know if it's a bug or a well-defined behaviour (I 
almost never rebind globals in functions..), I agree that this is at 
least weird since the compilation phase already tags the name as local 
wherever it's bound in the function.

Here's a minimal code reproducing the problem:

cnt = 1
test = 1 # set this to 0 to have an UnboundLocalError in wontdo()
retest = 1
def wontdo():
     global test
     global restest

     while test < retest:
         while cnt:
             cnt = cnt - 1
         test += 1


Some guru on this ?


NB : tested with
Python 2.5.1 (r251:54863, May  2 2007, 16:56:35)
[GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2



(snip)



More information about the Python-list mailing list