[ Team LiB ] |
13.1 Scope RulesNow that you will begin to write your own functions, we need to get 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—a place where names live. When we talk about the search for a name's value in relation to code, the term scope refers to a namespace—the location of a name's assignment in your code determines the scope of the name's visibility to your code. Just about everything related to names happens at assignment in Python—even scope classification. As we've seen, names in Python spring into existence when they are first assigned a value, and must be assigned before they are used. Because names are not declared ahead of time, Python uses the location of the assignment of a name to associate it with (i.e., bind it to) a particular namespace. That is, the place where you assign a name determines the namespace it will live in, and hence its scope of visibility. Besides packaging code, functions add an extra namespace layer to your programs—by default, all names assigned inside a function are associated with that function's namespace, and no other. This means that:
The net effect is that function scopes help avoid name clashes in your programs, and help to make functions more self-contained program units. 13.1.1 Python Scope BasicsBefore you started writing functions, all code was written at the top-level of a module (i.e., not nested in a def), so the names either lived in the module itself, or were built-ins that Python predefines (e.g., open).[1] Functions provide a nested namespace (i.e., 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). Functions define a local scope, and modules define a global scope. The two scopes are related as follows:
Note that any type of assignment within a function classifies a name as local: = statements, imports, defs, argument passing, and so on. Also notice that in-place changes to objects do not classify names as locals; only actual name assignments do. For instance, if name L is assigned to a list at the top level of a module, a statement like L.append(X) within a function will not classify L as a local, whereas L = X will. In the former case, L will be found in the global scope as usual, and change the global list. 13.1.2 Name Resolution: The LEGB RuleIf the prior section sounds confusing, it really boils down to three simple rules:
In other words, all names assigned inside a function def statement (or lambda—an expression we'll meet later) are locals by default; functions can use both names in lexically (i.e., physically) enclosing functions and the global scope, but they must declare globals to change them. Python's name resolution is sometimes called the LEGB rule, after the scope names:
Figure 13-1 illustrates Python's four scopes. Note that the second "E" scope lookup layer—enclosing defs or lambdas—technically can correspond to more than one lookup layer. It only comes into play when you nest functions within functions.[2]
Figure 13-1. The LEGB scope lookup ruleAlso, keep in mind that these rules only apply to simple variable names (such as spam). In Parts Part V and Part VI, we'll see that the rules for qualified attribute names (such as object.spam) live in a particular object and follow a completely different set of lookup rules than the scope ideas covered here. Attribute references (names following periods) search one or more objects, not scopes, and may invoke something called inheritance discussed in Part VI. 13.1.3 Scope ExampleLet'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 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:
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; these names 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. Because you can be sure that local names are not changed by some remote function in your program, they also tend to make programs easier to debug. 13.1.4 The Built-in ScopeWe've been talking about the built-in scope in the abstract, but it's a bit simpler than you may think. Really, the built-in scope is just a prebuilt standard library module called __builtin__, which you can import and inspect if you want to see which names are predefined: >>> import __builtin__ >>> dir(__builtin__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning', 'EOFError', 'Ellipsis', ...many more names ommitted... 'str', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] The names in this list are the built-in scope in Python; roughly the first half are built-in exceptions, and the second are built-in functions. Because Python automatically searches this module last in its LEGB lookup rule, you get all the names in this list for free—they can be used without importing any module. In fact, there are two ways to refer to a built-in function: by the LEGB rule, or by manually importing: >>> zip # The normal way <built-in function zip> >>> import __builtin__ # The hard way >>> __builtin__.zip <built-in function zip> The second of these is sometimes useful in advanced work. The careful reader might also notice that, because the LEGB lookup procedure takes the first occurrence of a name that it finds, names in the local scope may override variables of the same name in both the global and built-in scopes, and global names may override built-ins. A function can, for instance, create a local variable called open by assigning to it: def hider( ): open = 'spam' # Local variable, hides built-in ... However, this will hide the built-in function called open that lives in the built-in (outer) scope. It's also usually a bug, and a nasty one at that, because Python will not issue a message about it—there are times in advanced programming where you may really want to replace a built-in name by redefining it in your code. Functions can similary hide global variables of the same name with locals: X = 88 # Global X def func( ): X = 99 # Local X: hides global func( ) print X # Prints 88: unchanged Here, the assignment within the function creates a local X that is a competely different variable than the global X in the module outside the function. Because of this, there is no way to change a name outside the function, without adding a global declaration to the def—as described in the next section. |
[ Team LiB ] |