I l@ve RuBoard Previous Section Next Section

4.3 Scope Rules in Functions

Now that we've stepped up to writing our own functions, we need to get a bit more formal about what names mean in Python. When you use a name in a program, Python creates, changes, or looks up the name in what is known as a namespace梐 place where names live. As we've seen, names in Python spring into existence when they are assigned a value. Because names aren't declared ahead of time, Python uses the assignment of a name to associate it with a particular namespace. Besides packaging code, functions add an extra namespace layer to your programs梑y default, names assigned inside a function are associated with that function's namespace, and no other.

Here's how this works. Before you started writing functions, all code was written at the top-level of a module, so the names either lived in the module itself, or were built-ins that Python predefines (e.g., open).[3] Functions provide a nested namespace (sometimes called a scope), which localizes the names they use, such that names inside the function won't clash with those outside (in a module or other function). We usually say that functions define a local scope, and modules define a global scope. The two scopes are related as follows:

[3] Remember, code typed at the interactive command line is really entered into a built-in module called __main__, so interactively created names live in a module too. There's more about modules in Chapter 5.

The enclosing module is a global scope

Each module is a global scope梐 namespace where variables created (assigned) at the top level of a module file live.

Each call to a function is a new local scope

Every time you call a function, you create a new local scope梐 namespace where names created inside the function usually live.

Assigned names are local, unless declared global

By default, all the names assigned inside a function definition are put in the local scope (the namespace associated with the function call). If you need to assign a name that lives at the top-level of the module enclosing the function, you can do so by declaring it in a global statement inside the function.

All other names are global or built-in

Names not assigned a value in the function definition are assumed to be globals (in the enclosing module's namespace) or built-in (in the predefined names module Python provides).

4.3.1 Name Resolution: The LGB Rule

If the prior section sounds confusing, it really boils down to three simple rules:

In other words, all names assigned inside a function def statement are locals by default; functions can use globals, but they must declare globals to change them. Python's name resolution is sometimes called the LGB rule, after the scope names:

Figure 4.1 illustrates Python's three scopes. As a preview, we'd also like you to know that these rules only apply to simple names (such as spam). In the next two chapters, we'll see that the rules for qualified names (such as object.spam, called attributes) live in a particular object and so work differently.

Figure 4.1. The LGB scope lookup rule

4.3.2 Example

Let's look at an example that demonstrates scope ideas. Suppose we write the following code in a module file:

# global scope
X = 99                # X and func assigned in module: global
def func(Y):          # Y and Z assigned in function: locals
    # local scope
    Z = X + Y         # X is not assigned, so it's a global
    return Z

func(1)               # func in module: result=100

This module, and the function it contains, use a number of names to do their business. Using Python's scope rules, we can classify the names as follows:

Global names: X , func

X is a global because it's assigned at the top level of the module file; it can be referenced inside the function without being declared global. func is global for the same reason; the def statement assigns a function object to the name func at the top level of the module.

Local names: Y , Z

Y and Z are local to the function (and exist only while the function runs), because they are both assigned a value in the function definition; Z by virtue of the = statement, and Y because arguments are always passed by assignment (more on this in a minute).

The whole point behind this name segregation scheme is that local variables serve as temporary names you need only while a function is running. For instance, the argument Y and the addition result Z exist only inside the function; they don't interfere with the enclosing module's namespace (or any other function, for that matter). The local/global distinction also makes a function easier to understand; most of the names it uses appear in the function itself, not at some arbitrary place in a module.[4]

[4] The careful reader might notice that, because of the LGB rule, names in the local scope may override variables of the same name in the global and built-in scopes, and global names may override built-ins. A function can, for instance, create a local variable called open, but it will hide the built-in function called open that lives in the built-in (outer) scope.

4.3.3 The global Statement

The global statement is the only thing that's anything like a declaration in Python. It tells Python that a function plans to change global names梟ames that live in the enclosing module's scope (namespace). We've talked about global in passing already; as a summary:

The global statement is just the keyword global, followed by one or more names separated by commas. All the listed names will be mapped to the enclosing module's scope when assigned or referenced within the function body. For instance:

y, z = 1, 2         # global variables in module

def all_global():
    global x        # declare globals assigned
    x = y + z       # no need to declare y,z: 3-scope rule

Here, x, y, and z are all globals inside function all_global. y and z are global because they aren't assigned in the function; x is global because we said so: we listed it in a global statement to map it to the module's scope explicitly. Without the global here, x would be considered local by virtue of the assignment. Notice that y and z are not declared global; Python's LGB lookup rule finds them in the module automatically. Also notice that x might not exist in the enclosing module before the function runs; if not, the assignment in the function creates x in the module.

I l@ve RuBoard Previous Section Next Section