Variable scoping rules in Python?

Diez B. Roggisch deets at nospam.web.de
Mon Oct 8 16:24:00 CEST 2007


 joshua.davies at travelocity.com wrote:

> Ok, I'm relatively new to Python (coming from C, C++ and Java).  I'm
> working on a program that outputs text that may be arbitrarily long,
> but should still line up, so I want to split the output on a specific
> column boundary.  Since I might want to change the length of a column,
> I tried defining the column as a constant (what I would have made a
> "#define" in C, or a "static final" in Java).  I defined this at the
> top level (not within a def), and I reference it inside a function.
> Like this:
> 
> COLUMNS = 80
> 
> def doSomethindAndOutputIt( ):
>   ...
>   for i in range( 0, ( len( output[0] ) / COLUMNS ) ):
>     print output[0][ i * COLUMNS : i * COLUMNS + ( COLUMNS - 1 ) ]
>     print output[1][ i * COLUMNS : i * COLUMNS + ( COLUMNS - 1 ) ]
>     ..
> 
> etc. etc.  It works fine, and splits the output on the 80-column
> boundary just like I want.
> 
> Well, I decided that I wanted "COLUMNS = 0" to be a special "don't
> split anywhere" value, so I changed it to look like this:
> 
> COLUMNS = 80
> 
> def doSomethindAndOutputIt( ):
>   ...
>   if COLUMNS == 0:
>     COLUMNS = len( output[ 0 ] )
> 
>   for i in range( 0, ( len( output[0] ) / COLUMNS ) ):
>     print output[0][ i * COLUMNS : i * COLUMNS + ( COLUMNS - 1 ) ]
>     print output[1][ i * COLUMNS : i * COLUMNS + ( COLUMNS - 1 ) ]
>     ..
> 
> Now, when I run it, I get the following error:
> 
> Traceback (most recent call last):
>   File "Test.py", line 140, in ?
>     doSomethingAndOutput( input )
>   File "Test.py", line 123, in doSomethingAndOutput
>     if COLUMNS == 0:
> UnboundLocalError: local variable 'COLUMNS' referenced before
> assignment
> 
> I went back and re-read chapter 13 of "Learning Python", which talks
> about variable scoping rules, and I can't figure out why Python is
> saying this variable in Unbound.  It works if I insert:
> 
>   global COLUMNS
> 
> before the "if" statement... but I don't understand why.  Is the
> interpreter scanning my entire function definition before executing
> it, recognizing that I *might* assign COLUMNS to a value, and deciding
> that it's a local on that basis?

Yep. That's essentially it. Because python has no explicit variable
declaration, it looks on the left hand side of assignments to determine the
locals. 

Diez



More information about the Python-list mailing list