Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Chapter 10. Additional Notes On Functions

The global Statement

We cover some more advanced techniques available in Python in the section called “Returning Multiple Values”. In the section called “Functions and Namespaces” we'll describe some of the internal mechanisms Python uses for storing variables. We'll introduce the global statement in the section called “The global Statement”. We'll include a digression on the two common argument binding mechanisms: call by value and call by reference in the section called “Call By Value and Call By Reference”. Finally, we'll cover some aspects of functions as first-class objects in the section called “Function Objects”.

Functions and Namespaces

This is an overview of how Python determines the meaning of a name. We'll omit some details to hit the more important points. For more information, see section 4.1 of the Python Language Reference.

The important issue is that we want variables created in the body of a function to be private to that function. If all variables are global, then each function runs a risk of accidentally disturbing the value of a global variable. In the COBOL programming language (without using separate compilation or any of the moden extensions) all variables are globally declared in the data division, and great care is required to prevent accidental or unintended use of a variable.

To achieve privacy and separation, Python maintains several dictionaries of variables. These dictionaries define the context in which a variable name is understood. Because these dictionaries are used for resolution of variables, which name objects, they are called namespaces. A global namespace is available to all modules that are part of the currently executing Python script. Each module, class, function, lambda, or anonymous block of code given to the exec command has its own private namespace.

Names are resolved using the nested collection of namespaces that define an execution environment. The Python always checks the most-local dictionary first, ending with the global dictionary.

Consider the following script.

def deep( hi, mom ):
    
do some work

    
def shallow( hows, things ):
    deep( hows, 1 )
    deep( things, coffee )

hows="a"
coffee="b"
shallow( hows, coffee )
3

This is the main function, it executes in the global namespace, where two variables are defined, along with two functions, deep and shallow.

2

The shallow function has a local namespace, where two variables are defined: hows and things. When shallow is called from the main script, the local hows hides the global variable with the same name. The reference to coffee is not resolved in the local namespace, but is resolved in the global namespace. This is called a free variable, and is sometimes a symptom of poor software design.

1

The deep function has a local namespace, where two variables are defined: hi and mom. When deep is called from shallow, there are three nested scopes that define the environment: the local namespace for deep, the local namespace for shallow, and the global namespace for the main script.

Built-in Functions. If you evaluate the function globals, you'll see the mapping that contains all of the global variables Python knows about. For these early programs, all of our variables are global.

If you simply evaluate locals, you'll see the same thing. However, if you call locals from within the body of a function, you'll be able to see the difference between local and global variables.

The following example shows the creation of a gobal variable a, and a global function, q. It shows the local namespace in effect while the function is executing. In this local namespace we also have a variable named a.

>>> 
a=22.0

>>> 
globals()

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__d
oc__': None, 'a': 22.0}

>>> 
def q( x, y ):

... 
    a = x / y

... 
    print locals()

... 
>>> 
locals()

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'q':
 <function q at 0x007E5EF0>, '__doc__': None, 'a': 22.0}

>>> 
globals()

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'q':
 <function q at 0x007E5EF0>, '__doc__': None, 'a': 22.0}

>>> 
q(22.0,7.0)

{'a': 3.1428571428571428, 'y': 7.0, 'x': 22.0}

>>>

The function vars ( context ) accepts a parameter which is the name of a specific local context: a module, class, or object. It returns the local variables for that specific context. The local variables are kept in a local variable named __dict__. The vars function retrieves this.

The dir ( object ) function examines the __dict__ of a specific object to locate all local variables as well as other features of the object.

Assignment statements, as well as def and class statements, create names in the local dictionary. The del statement removes a name from the local dictionary.

Some Consequences. Since each imported module exists in it's own namespace, all functions and classes within that module must have their names qualified by the module name. We saw this when we imported math and random. To use the sqrt function, we must say math.sqrt, providing the module name that is used to resolve the name sqrt.

This module namespace assures that everything in a module is kept separate from other modules. It makes our programs clear by qualifying the name with the module that defined the name.

The module namespace also allow a module to have relatively global variables. A module, for example, can have variables that are created when the module is imported. In a sense these are global to all the functions and classes in the module. However, because they are only known within the module's namespace, they won't conflict with variables in our program or other modules.

Having to qualify names within a module can become annoying when we are making heavy use of a module. Python has ways to put elements of a module into the global namespace. We'll look at these in Part IV, “Components, Modules and Packages”.


 
 
  Published under the terms of the Open Publication License Design by Interspire