Log in / Register
Home arrow Computer Science arrow Data Structures and Algorithms with Python
< Prev   CONTENTS   Next >

3.2 Scope

To form a complete mental picture of how your programs work we should further explore just how the Python interpreter executes a Python program. In the first chapter we explored how references are the things which we name and that references point to objects, which are unnamed. However, we sometimes call an object by the name of the reference that is pointing at it. For instance, if we write:

x = 6

it means that x is a reference that points to an object with a 6 inside it. But sometimes we are careless and just say that x equals 6. It is important that you understand that even when we say things like x equals 6 what we really mean is that x is a reference that points to an object that contains 6. You can see why we are careless sometimes. It takes too many words to say what we really mean and as long as everyone understands that references have names and objects are pointed to by references, then we can save the words. The rest of this text will make this assumption at times. When it is really important, we'll make sure we distinguish between references and objects.

Part of our mental picture must include Scope in a Python program. Scope refers to a part of a program where a collection of identifiers are visible. Let's look at a simple example program.

3.2.1 Local Scope

Consider the code in Fig. 3.2. In this program there are several scopes. Every colored region of the figure delimits one of those scopes. While executing line 23 of the program in Fig. 3.2 the light green region is called the Local scope. The local scope is the scope of the function that the computer is currently executing. When your program is executing a line of code, the scope that surrounds that line of code is called the local scope. When you reference an identifier in a statement in your program, Python first examines the local scope to see if the identifier is defined there, within the local scope. An identifier, id, is defined under one of three conditions.

• A statement like id = … appears somewhere within the current scope. In this case

id would be a reference to an object in the local scope.

id appears as a parameter name of the function in the current scope. In this case id would be a reference to an object that was passed to the current function as an argument.

id appears as a name of a function or class through the use of a function def or

class definition within the current scope.

While Python is executing line 23 in Fig. 3.2, the reference val is defined within its local scope. If Python finds id in the local scope, it looks up the corresponding value and retrieves it. This is what happens when val is encountered on line 23. The object that is referenced by val is retrieved and returned.

Fig. 3.2 Scopes within a Simple Program

3.2.2 Enclosing Scope

If Python does not find the reference id within the local scope, it will examine the Enclosing scope to see if it can find id there. In the program in Fig. 3.2, while Python is executing the statement on line 23, the enclosing scope is the purple region of the program. The identifiers defined in this enclosing scope include historyOfPrompts, historyOfOutput, rString, r, val, getInput, and showInput. Notice that function names are included as identifiers. Again, Python looks for the identifier using the same conditions as defined in Sect. 3.2.1 for the local scope. The identifier must be defined using id = …, it must be a parameter to the enclosing function, or it must be an identifier for a class or function definition in the enclosing scope's function. On line 23, when Python encounters the identifier historyOfOutput it finds that identifier defined in the enclosing scope and retrieves it for use in the call to the append method.

Which scope is local depends on where your program is currently executing. When executing line 23, the light green region is the local scope. When executing line 18 the brown region is the local scope. When executing line 14 or line 26 the purple region is the local scope. When executing line 6 the darker green region is the local scope. Finally, when executing line 1 or 3 the blue region is the local scope. The local scope is determined by where your program is currently executing.

Scopes are nested. This means that each scope is nested inside another scope. The final enclosing scope of a module is the module itself. Each module has its own scope. The blue region of Fig. 3.2 corresponds to the module scope. Identifiers that are defined outside of any other functions, but inside the module, are at the module level. The reference PI in Fig. 3.2 is defined at the module level. The functions area and main are also defined at the module level scope.

While executing line 23 of the program in Fig. 3.2 the identifier val is defined in the local scope. But, val is also defined in the enclosing scope. This is acceptable and often happens in Python programs. Each scope has its own copy of identifiers. The choice of which val is visible is made by always selecting the innermost scope that defines the identifier. While executing line 23 of the program in Fig. 3.2 the val in the local scope is visible and the val in the enclosing scope is hidden. This is why it is important that we choose our variable names and identifiers carefully in our programs. If we use an identifier that is already defined in an outer scope, we will no longer be able to access it from an inner scope where the same identifier is defined.

It is relatively easy to determine all the nested scopes within a module. Every function definition (including the definition of methods) within a module defines a different scope. The scope never includes the function name itself, but includes its parameters and the body of the function. You can follow this pattern to mentally draw boxes around any scope so you know where it begins and ends in your code.

3.2.3 Global Scope

Using Python it is possible to define variables at the Global level. Generally this is a bad programming practice and we will not do this in this text. If interested you can read more about global variables in Python online. But, using too many global variables will generally lead to name conflicts and will likely lead to unwanted side effects. Poor use of global variables contributes to spaghetti code which is named for the big mess you would have trying to untangle it to figure out what it does.

3.2.4 Built-In Scope

The final scope in Python is the Built-In scope. If an identifier is not found within any of the nested scopes within a module and it is not defined in the global scope, then Python will examine the built-in identifiers to see if it is defined there. For instance, consider the identifier int. If you were to write the following:

x = int("6")

Python would first look in the local scope to see if int were defined as a function or variable within that local scope. If int is not found within the local scope, Python would look in all the enclosing scopes starting with the next inner-most local scope and working outwards from there. If not found in any of the enclosing scopes, Python would then look in the global scope for the int identifier. If not found there, then Python would consult the Built-In scope, where it would find the int class or type.

With this explanation, it should now be clear why you should not use identifiers that already exist in the built-in scope. If you use int as an identifier you will not be able to use the int from the built-in scope because Python will find int in a local or enclosing scope first.

3.2.5 LEGB

Mark Lutz, in his book Learning Python [6], described the rules of scope in Python programs using the LEGB acronym. This acronym, standing for Local, Enclosing, Global, and Built-In can help you memorize the rules of scope in Python. The order of the letters in the acronym is important. When the Python interpreter encounters an identifier in a program, it searches the local scope first, followed by all the enclosing scopes from the inside outward, followed by the global scope, and finally the built-in scope.

Found a mistake? Please highlight the word and press Shift + Enter  
< Prev   CONTENTS   Next >
Business & Finance
Computer Science
Language & Literature
Political science