Linux/Unix > Python Essential Reference, Second Edition > 6. Functions and Functional Programming > Scoping Rules | See All Titles

< BACK | Make Note | Bookmark | CONTINUE >

155117184014003188065099048180054212144238241179195140058238110137104016132046068203195106

### Scoping Rules

Each time a function executes, a new local namespace is created. This namespace contains the names of the function parameters, as well as the names of variables that are assigned inside the function body. When resolving names, the interpreter first searches the local namespace. (See the comments on the next page regarding nested scopes.) If no match exists, it searches the global namespace. The global namespace for a function is always the module in which the function was defined. If the interpreter finds no match in the global namespace, it makes a final check in the built-in namespace. If this fails, a `NameError` exception is raised.

One peculiarity of namespaces is the manipulation of global variables from within a function. For example, consider the following code:

    a = 42
    def foo():
        a = 13
    foo()
    print a

When executed, the value `42` prints, despite the appearance that we might be modifying the variable `a` inside the function `foo`. When variables are assigned in a function, they’re always bound to the function’s local namespace; as a result, the variable `a` in the function body refers to an entirely new object containing the value `13`. To alter this behavior, use the `global` statement. `global` simply marks a list of names as belonging to the global namespace, and is necessary only when global variables will be modified. It can be placed anywhere in a function body and used repeatedly. For example:

    a = 42
    def foo():
        global a        # 'a' is in global namespace
        a = 13
    foo()
    print a

All versions of Python allow nested function definitions. However, prior to Python 2.1, nested functions didn’t provide nested scopes. As a result, a program using a nested function might not work as you expect. For example in Python 2.0, the following program is legal, but doesn’t execute properly:

    def bar():
      x = 10
      def spam():            # Nested function definition
           print 'x is ', x  # Looks for x in global scope of bar()
      while x > 0:
           spam()            # Fails with a NameError on 'x'
           x -= 1

In this case, when the nested function `spam()` executes, its global namespace is the same as the global namespace for `bar()`, the module in which the function is defined. As a result, `spam()` is unable to resolve any symbols in the namespace of `bar()` and fails with a `NameError`.

Starting with Python 2.1, support for nested scopes is provided (so the above example will work). With nested scopes, names are resolved by first checking the local scope and then all enclosing scopes. If no match is found, the global and built-in namespaces are checked as before. Note that in Python 2.1 nested scopes are an optional feature that must be enabled by including `from _ _future_ _ import nested_scopes` in your program (see Chapter 10, “Execution Environment”). In addition, if you care about compatibility with older versions of Python, avoid using nested functions.

If a local variable is used before it’s assigned a value, an `UnboundLocalError` exception is raised. For example:

    def foo():
        print i       # Results in UnboundLocalError exception
        i = 0

| Last updated on 3/28/2002 Python Essential Reference, Second Edition, © 2002 New Riders Publishing

< BACK | Make Note | Bookmark | CONTINUE >

© 2002, O'Reilly & Associates, Inc.