problem with variable scoping

Martijn Faassen faassen at pop.vet.uu.nl
Wed May 26 16:17:19 EDT 1999


Michael Dingler wrote:
> 
> It's...
> 
> an embarassing question. Yes folks, I'm writing my first
> Python program (a text to HTML converter) and I have a
> slight misunderstanding with the variable scoping...
> 
> Let me present some code fragments:
> 
> last_line_empty = 0
> .
> .
> .
> def process(line):
>         ...
>         if last_line_empty:
>                 pass
>         else:
>                 print "<P>"
>         last_line_empty = 1
> 
> You see, I want to replace empty lines with paragraph symbols,
> but if there is more than one, I want just one <p>-tag... If
> I leave out the last statement (setting last_line_empty to one),
> it works, but otherwise I get a 'name error' on the 'if' line.

Short answer:

Try using 'global':

def process(line):
    # tell this function that last_line_empty exists and is a global
    global last_line_empty 
    if last_line_empty:
    ...

Long explanation:

Whenever an assignment to a local variable occurs in a Python function
(such as last_line_empty = 1, Python by default always assigns to the
innermost scope), that variable is assumed to be in the function's local
namespace. Any lookups of that variable inside the function that occur
before the variable is defined fail, identical to the case where you
don't define the global variable last_line_empty.

This, for instance, will do unexpected things:

myglob = 1
def foo():
    myglob = 0
foo()
print myglob # prints 1!

This does what you'd expect:
myglob = 1
def foo():
   global myglob
   myglob = 0
foo()
print myglob # prints 0

The tricky bit is that this works:
myglob = 1
def foo():
    print myglob
foo() # prints 1, no NameError

If no assignment to myglob occurs in the function's namespace the global
namespace is used.

This all has interesting reasons and consequences that Tim Peters can
tell you the advantages of. :)

Note that it's good practice to try to avoid global variables in your
program (though they're useful sometimes, of course). Python provides
classes that often provide a more elegant solution; you can use a member
variable instead of a global variable.

Also take a look at StructuredText, a Python module that's part of
Digital Creation's Zope (www.zope.org), but can be used independently.
It does something similar to what you are trying to accomplish, I think.

Regards,

Martijn




More information about the Python-list mailing list