next up previous contents
Next: Test Programs for Modules Up: Writing Modules Previous: Introduction   Contents

An Example

As a simple example of a module, we'll write three functions which would be useful if you were working with files. The first, which we'll call lline, will return the length of the longest line encountered in a file. The second, which we'll call wcount will be a python version of the UNIX command wc, which, given a file name, returns the number of lines, words and characters contained in the file. The final function, which we'll call ccount, will count the number of occurences of a given character in a file. To make these functions available for use in programs, we'll store the python code for these three functions in a file called fileutil.py, stored in either the current directory, or one of the directories in the python search path. The following code implements these three functions:
def lline(filename):
    f = open(filename,'r')
    longest = 0
    for line in f:
        lennow = len(line) - 1
        if lennow > longest:
            longest = lennow
    f.close()
    return longest

def wcount(filename):
    f = open(filename,'r')
    nlines = nwords = nchars = 0
    for line in f:
        nlines = nlines + 1
        nwords = nwords + len(line.split())
        nchars = nchars + len(line)
    f.close()
    return (nlines,nwords,nchars)

def ccount(filename,char='\t'):
    f = open(filename,'r')
    found = 0
    for line in f:
        found = found + line.count(char)
    f.close()
    return found
A few comments on the design of these functions is in order. Notice that, unlike previous examples, the calls to open are not enclosed in a try/except clause. Since these functions are designed to be imported into a program which will call them, the decision was made to allow any exceptions which are raised to ``filter up'' to the calling program, where the programmer who was calling the functions would be expected to deal with them This is a decision which should not be ignored when designing a module; in the current example, since there's not much that these functions can do if they can't open the file that was passed to them, the decision to pass the responsibility of dealing with exceptions to the caller of the function seemed reasonable. In other cases, it might be more appropriate to trap the exception, especially when some useful alternative in the face of the exception is possible.

In the lline function, the newline was not included in the length of the longest line - in practice, it might be more useful to pass another argument to the function which would allow you to include the newline in the reported length.

In the ccount function, the default character to search for is defined to be a tab. This is an arbitrary choice, but it would make the function easy to use when trying to decide whether or not to use white space or tabs as a separator when reading data from a file. For other situations, a different default character might be more reasonable.

To use these functions, we can simply import them in the usual way (provided they reside in a directory on python's search path.) For example, to check a list of files passed on the command line to insure that none of them have any lines longer than 80 characters, we could write a program like the following one:

#!/usr/local/bin/python

import sys,fileutil

for file in sys.argv[1:]:
    ll = fileutil.lline(file)
    if ll > 80:
        print 'Long line (%d chars) found in %s' % (ll,file)

If you only needed one function from the module, individual functions could be imported from fileutil in the usual way (See Section 8.2). In fact, once you've written a module in Python, and that module's directory is on the Python search path, there's very little difference between a user-written module and a module that's a part of Python itself.


next up previous contents
Next: Test Programs for Modules Up: Writing Modules Previous: Introduction   Contents
Phil Spector 2003-11-12