Fundamentals » Creating Modules »

 

Creating Modules

Defining Functions Table Of Contents List Basics


As you learned earlier, Python includes a standard library containing modules of functions and class definitions which we have used in a number of our programs. By using modules, the language itself can remain relatively small while still providing extended functionallity.

Python programs can quickly become very large and unmanagable if the entire user code is placed within a single source file. To help structure and manage large programs, Python allows the user to create their own modules. These modules can be used to group class definitions and related functions and then imported as needed.

Typically, a large program consists of a top-level source file and one or more supplemental modules. The top-level file acts as the driver which contains the statements for the main flow of execution. The modules then contain related components which act as tools that are used as needed.

Structured Program

The following example illustrates the use of modules to organize and structure a program. It consists of three Python source files: driver.py, modA.py, and modB.py.

# driver.py
# The driver file which contains the statements creating
# the main flow of execution.

import modA
import modB

value1 = int( raw_input( "Enter value one: " ) )
value2 = int( raw_input( "Enter value two: " ) )
resultA = modA.funcA( value1, value2 )
resultB = modB.funcB( resultA )
print "Results = ", resultA, resultB

# ---------------------------------------------------------
# modA.py
# A user-defined module which defines a function and
# imports a standard module.

from math import *

def funcA( x, y ) :
  d = sqrt( x * x + y * y )
  return d

# ---------------------------------------------------------
# modB.py
# A second user-defined module which defines a function and
# imports the other user-defined module as well as a
# standard module.

from modA import *

def funcB( a ) :
  b = funcA( a, a * 4 )
  return b / 3 + funcC()

def funcC( x = 0 ) :
  return x * 12
 

The structure of this program is illustrated graphically in the following diagram.

Multiple Inclusions

Module modA is imported in both driver.py and modB.py since its contents is used in both. The Python interpreter will only import a module once, even if it encountered multiple times. You should import a module within a source file if any component of that module is used. Let the interpreter omit it, if it has already been included.

Program Execution

To execute the program, you would enter the following

  python driver.py

at the command-line prompt since the driver program is the main file containing the starting point of execution.

Importing The Modules

The modules are simply Python source files and thus have a .py extension. When importing a module, however, you omit the extension. The examples in this book assume the modules are stored in the same directory as the driver program.

As you learned earlier, Python includes a standard library containing modules of functions and class definitions which we have used in a number of our programs. By using modules, the language itself can remain relatively small while still providing extended functionallity.

Python programs can quickly become very large and unmanagable if the entire user code is placed within a single source file. To help structure and manage large programs, Python allows the user to create their own modules. These modules can be used to group class definitions and related functions and then imported as needed.

Typically, a large program consists of a top-level source file and one or more supplemental modules. The top-level file acts as the driver which contains the statements for the main flow of execution. The modules then contain related components which act as tools that are used as needed.

Structured Program

The following example illustrates the use of modules to organize and structure a program. It consists of three Python source files: driver.py, modA.py, and modB.py.

# driver.py
# The driver file which contains the statements creating
# the main flow of execution.

import modA
import modB

value1 = int( raw_input( "Enter value one: " ) )
value2 = int( raw_input( "Enter value two: " ) )
resultA = modA.funcA( value1, value2 )
resultB = modB.funcB( resultA )
print "Results = ", resultA, resultB

# ---------------------------------------------------------
# modA.py
# A user-defined module which defines a function and
# imports a standard module.

from math import *

def funcA( x, y ) :
  d = sqrt( x * x + y * y )
  return d

# ---------------------------------------------------------
# modB.py
# A second user-defined module which defines a function and
# imports the other user-defined module as well as a
# standard module.

from modA import *

def funcB( a ) :
  b = funcA( a, a * 4 )
  return b / 3 + funcC()

def funcC( x = 0 ) :
  return x * 12
 

The structure of this program is illustrated graphically in the following diagram.

Multiple Inclusions

Module modA is imported in both driver.py and modB.py since its contents is used in both. The Python interpreter will only import a module once, even if it encountered multiple times. You should import a module within a source file if any component of that module is used. Let the interpreter omit it, if it has already been included.

Program Execution

To execute the program, you would enter the following

  python driver.py

at the command-line prompt since the driver program is the main file containing the starting point of execution.

Importing The Modules

The modules are simply Python source files and thus have a .py extension. When importing a module, however, you omit the extension. The examples in this book assume the modules are stored in the same directory as the driver program.

Namespaces

All identifiers in Python live within a namespace — the context in which identifers are defined. You can think of a namespace as a container or index in which various identifiers are stored. When an indentifer is referenced in a Python program, a search is performed in particular namespace to determine if that identifier is valid. The namespace concept allows us to create duplicate names, each existing in a different namespace.

In Python, each module constitutes its own namespace. Any identifier declared within a module, may be freely used within that same module. Consider the modB module from above which defines two functions, funcB() and funcC(). Notice that funcC() is called from within funcB()

def funcB( a ) :
  b = funcA( a, a * 4 )
  return b / 3 + funcC()
 

which is valid since both are in the same namespace. But what about the call to funcA()? There is no such function within the modB module. That function resides in the module modA and was made available via the statement

from modA import *
 

When the from/import statement is used, it includes the module and makes its contents available for use in the current module, but it also includes the identifiers from the imported module into the namespace of the current module. That is why we can refer to funcA() as if it were defined within the modB namespace, even though it was defined within the modA namespace. The same is true for the sqrt() function used in the module modA. That function was defined in the math namespace, but has been imported and made a part of the modA namespace.

Next, let’s examine the first two statements in the driver.py file

import modA
import modB
 

These statements include the indicated modules and make their contents available for use within the driver.py file. But, there is a major difference between this version and the from/import version. With the plain import statement, the identifers declared within the imported module’s namespace are not made a part of the current module’s namespace. Their namespace remains that in which they were defined, modA and modB, respectively.

Identifers defined within a different namespace, which have not been made a part of the current namespace can still be accessed. In the driver file, we make calls to funcA() and funcB()

resultA = modA.funcA( value1, value2 )
resultB = modB.funcB( resultA )
 

But you will notice the function name is preceded with the module name in which it was defined. By doing this, we tell the interpreter that we are referencing funcA() from the modA namespace and funcB() from the modB namespace. Note, that even though we indicate the namespace for the functions, the modules themselves still have to be included via the import statement.

You may be asking why there are two methods to import modules. Why not just use the from/import version and make all identifiers available within the current module? The short answer is there are times when different module authors may use the same name for a function or class, yet provide different functionality. Consider the following example

# ---------------------------------------------------------
# main.py

import modA
import modC

x = int( raw_input( "Enter value one: " ) )
y = int( raw_input( "Enter value two: " ) )
v = modA.funcA( x, y )
w = modC.funcA( x, y )

# ---------------------------------------------------------
# modA.py

from math import *

def funcA( x, y ) :
  d = sqrt( x * x + y * y )
  return d

# ---------------------------------------------------------
# modC.py

def funcA( x, y ) :
  return x + y
 

We want to reference both identifiers from within the driver program. If we had imported the indentifiers into the current namespace, then only the second one imported be known within the current namespace. By including the namespace as part of the reference, we direct the interpreter to the correct identifier.

The example program presented earlier in this chapter consists of three modules: driver, modA, and modB. We’ll examine the modB module first. , both of which reside in the modB namespace.



Defining Functions Table Of Contents List Basics

© 2006 - 2008: Rance Necaise - Page last modified on September 10, 2006, at 03:12 PM