Defining Your Own Modules

Section 2.1, The Big Picture, on page 17 explained that in order to save code for later use, you can put it in a file with a .py extension. You can then tell Python to run the code in that file, rather than typing commands in at the interactive prompt. What we didn't tell you then is that every Python file can be used as a module. The name of the module is the same as the name of the file, but without the .py extension.

For example, the following function is taken from Section 2.6, Function Basics, on page 30:

Download modules/convert.py

def to_celsius(t):

Put this function definition in a file called temperature.py, and then add another function called above_freezing that returns True if its argument's value is above freezing (in Celsius), and False otherwise:

Download modules/freezing.py

def above_freezing(t): return t > 0

Congratulations—you have now created a module called temperature:

Download modules/temperature.py

def to_celsius(t):

def above_freezing(t): return t > 0

Now that you've created this file, you can now import it like any other module:

Download modules/import_temp.cmd

>>> import temperature

>>> temperature.above_freezing(temperature.to_celsius(33.3)) True

The_builtins_Module

Python's built-in functions are actually in a module named

_builtins_. The double underscores before and after the name signal that it's part of Python; we'll see this convention used again later for other things. You can see what's in the module using help(__builtins__), or if you just want a directory, you can use dir instead (which works on other modules as well):

Download modules/dirl.cmd

['ArithmeticError' , 'AssertionError' , ' AttributeError' , 'BaseException', 'DeprecationWarning' , 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', ' FloatingPointError' , 'FutureWarning', 'GeneratorExit', 'IOError', ' ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError' , 'MemoryError', 'NameError', 'None', ' NotImplemented' , ' NotImplementedError' , 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError' , 'RuntimeError' , 'RuntimeWarning' , 'StandardError' , 'StopIteration', 'SyntaxError' , 'SyntaxWarning' , 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError' , 'UnicodeError' , 'UnicodeTranslateError', 'UnicodeWarning' , 'UserWarning' , 'ValueError' , 'Warning' , 'ZeroDivisionError' , '_',

'_debug_', '_doc_', '_import_', '_name_', 'abs', 'all',

'any', 'apply', 'basestring' , 'bool', 'buffer', 'callable' , 'chr', ' classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright' , 'credits' , 'delattr' , 'dict', 'dir', 'divmod', 'enumerate' , 'eval', 'execfile' , 'exit', 'file', 'filter', 'float', 'frozenset' , 'getattr', 'globals', 'hasattr' , 'hash', 'help', 'hex', 'id', 'input', 'int' , 'intern', 'isinstance', 'issubclass' , 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord' , 'pow' , 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr' , 'reversed', 'round', 'set', 'setattr' , 'slice', 'sorted', 'staticmethod' , 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode' , 'vars', 'xrange', 'zip']

As of Python 2.5, 32 of the 135 things in_builtins_are used to signal errors of particular kinds, such as SyntaxError and ZeroDivisionError. There are also functions called copyright, which tells you who holds the copyright on Python, and license, which displays Python's rather complicated license. We'll meet some of this module's other members in later chapters.

eoo

Wing IDE: temperature.py (/Users/jay)

File Edit Source Debug Tools

Wjndow Help

D New ife; Open... ||j§5ave |

|i: Save All Goto Definition

Search

► Run if) Break ^¡f Debug

HI Stop "¡¿[¡j Step Into §¡1 Step Over ¡|| Step Out

temperature, py fahr to eel temperature, py fahr to eel

4 def fltn>ve_f neezintj(t}:

Search | stack Data

Search: Replace.

Case sensitive Whole words

I__|n Selection

I Previous ^ Next Replace Replace All

FDebug I/O

Python Shell

V

Commands execute without debug. U: ▼Options

Python 2.5.1 (r251:54863, Jan 17 2Q08. [GCC 4.0.1 (Apple Inc. build 5465)]

Type "help", "copyright", "credits" or »>

ft

W

<C3

> >

Figure 4.2: The temperature module in Wing 101

What Happens During Import

Let's try another experiment. Put the following in a file called experi-ment.py:

Download modules/experiment.py

print "The panda's scientific name is 'Ailuropoda melanoleuca'" and then import it (or click Wing 101's Run button):

Download modules/import_experiment.cmd >>> import experiment

The panda's scientific name is 'Ailuropoda melanoleuca'

What this shows is that Python executes modules as it imports them. You can do anything in a module you would do in any other program, because as far as Python is concerned, it's just another bunch of statements to be run.

Let's try another experiment. Start a fresh Python session, and try importing the experiment module twice in a row:

Download modules/import_twice.cmd

>>> import experiment

The panda's scientific name is 'Ailuropoda melanoleuca'

>>> import experiment

Notice that the message wasn't printed the second time. That's because Python loads modules only the first time they are imported. Internally, Python keeps track of the modules it has already seen; when it is asked to load one that's already in that list, it just skips over it. This saves time and will be particularly important when you start writing modules that import other modules, which in turn import other modules—if Python didn't keep track of what was already in memory, it could wind up loading commonly used modules like math dozens of times.

Using_main_

As we've now seen, every Python file can be run directly from the command line or IDE or can be imported and used by another program. It's sometimes useful to be able to tell inside a module which is happening, in other words, whether the module is the main program that the user asked to execute or whether some other module has that honor.

Python defines a special variable called __name__ in every module to help us figure this out. Suppose we put the following into echo.py:

Download modules/echo.py

If we run this file, its output is as follows:

Download modules/echo.out

As promised, Python has created the variable __name__ . Its value is "_main_", meaning, "This module is the main program."

But look at what happens when we import echo.py, instead of running it directly:

Download modules/echo.cmd

The same thing happens if we write a program that does nothing but import our echoing module:

Download modules/import_echo.py

import echo print "After import, _name_ is", _name_, "and echo._name_ is", echo._name which, when run from the command line, produces this:

Download modules/import_echo.out

echo: name is echo

After import, _name_ is _main_ and echo._name_ is echo

What's happening here is that when Python imports a module, it sets that module's __name__ variable to be the name of the module, rather than the special string "__main__". This means that a module can tell whether it is the main program:

Download modules/test_main.py

print "I am the main program" else:

print "Someone is importing me"

Try it, and see what happens when you run it directly and when you import it.

Knowing whether a module is being imported or not turns out to allow a few handy programming tricks. One is to provide help on the command line whenever someone tries to run a module that's meant to be used as a library. For example, think about what happens when you run the following on the command line vs. importing it into another program:

Download modules/main_help.py

This module guesses whether something is a dinosaur or not.

def is_dinosaur(name): 11 i

Return True if the named create is recognized as a dinosaur, and False otherwise. 11 i return name in ['Tyrannosaurus', 'Triceratops']

We will see other uses in the following sections and in later chapters.

Providing Help

Let's return to the temperature module for a moment and modify it to round temperatures off. We'll put the result in temp_round.py:

Download modules/temp_round.py

def to_celsius(t):

def above_freezing(t): return t > 0

What happens if we ask for help on the function to_celsius?

Download modules/help_temp.cmd

>>> import temp_round >>> help(temp_round) Help on module temp_round:

NAME

temp_round

FILE

/home/pybook/modules/temp_round.py

FUNCTIONS

above_freezing(t)

to_celsius(t)

That's not much use: we know the names of the functions and how many parameters they need, but not much else. To provide something more useful, we should add docstrings to the module and the functions it contains and save the result in temp_with_doc.py:

Download modules/temp_with_doc.py

'''Functions for working with temperatures.'''

def to_celsius(t):

'''Convert Fahrenheit to Celsius.''' return round((t - 32.0) * 5.0 / 9.0)

def above_freezing(t):

'''True if temperature in Celsius is above freezing, False otherwise.''' return t > 0

Asking for help on this module produces a much more useful result.

Download modules/help_temp_with_doc.cmd

>>> import temp_with_doc >>> help(temp_with_doc) Help on module temp_with_doc:

NAME

temp_with_doc - Functions for working with temperatures.

FILE

/home/pybook/modules/temp_with_doc.py

FUNCTIONS

above_freezing(t)

True if temperature in Celsius is above freezing, False otherwise.

to_celsius(t)

Convert Fahrenheit to Celsius.

The term docstring is short for "documentation string." Docstrings are easy to create: if the first thing in a file or a function is a string that isn't assigned to anything, Python saves it so that help can print it later.

You might think that a module this small doesn't need much documentation. After all, it has only two functions, and their names are pretty descriptive of what they do. But writing documentation is more than a way to earn a few extra marks—it's essential to making software usable. Small programs have a way of turning into larger and more complicated ones. If you don't document as you go along and keep the documentation in the same file as the program itself, you will quickly lose track of what does what.

0 0

Post a comment

  • Receive news updates via email from this site