home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Previous Section Next Section

7.1 Module Objects

A module is a Python object with arbitrarily named attributes that you can bind and reference. The Python code for a module named aname normally resides in a file named aname.py, as covered in Section 7.2 later in this chapter.

In Python, modules are objects (values) and are handled like other objects. Thus, you can pass a module as an argument in a call to a function. Similarly, a function can return a module as the result of a call. A module, just like any other object, can be bound to a variable, an item in a container, or an attribute of an object. For example, the sys.modules dictionary, covered later in this chapter, holds module objects as its values.

7.1.1 The import Statement

You can use any Python source file as a module by executing an import statement in some other code. import has the following syntax:

import modname [as varname][,...]

The import keyword is followed by one or more module specifiers, separated by commas. In the simplest and most common case, modname is an identifier, the name of a variable that Python binds to the module object when the import statement finishes. In this case, Python looks for the module of the same name to satisfy the import request. For example:

import MyModule

looks for the module named MyModule and binds the variable named MyModule in the current scope to the module object. modname can also be a sequence of identifiers separated by dots (.) that names a module in a package, as covered in later in this chapter.

When as varname is part of an import statement, Python binds the variable named varname to the module object, but the module name that Python looks for is modname. For example:

import MyModule as Alias

looks for the module named MyModule and binds the variable named Alias in the current scope to the module object. varname is always a simple identifier.

7.1.1.1 Module body

The body of a module is the sequence of statements in the module's source file. There is no special syntax required to indicate that a source file is a module; any valid source file can be used as a module. A module's body executes immediately the first time the module is imported in a given run of a program. During execution of the body, the module object already exists and an entry in sys.modules is already bound to the module object.

7.1.1.2 Attributes of module objects

An import statement creates a new namespace that contains all the attributes of the module. To access an attribute in this namespace, use the name of the module object as a prefix:

import MyModule
a = MyModule.f(  )

or:

import MyModule as Alias
a = Alias.f(  )

Most attributes of a module object are bound by statements in the module body. When a statement in the body binds a variable (a global variable), what gets bound is an attribute of the module object. The normal purpose of a module body is exactly that of creating the module's attributes: def statements create and bind functions, class statements create and bind classes, assignment statements bind attributes of any type.

You can also bind and unbind module attributes outside the body (i.e., in other modules), generally using attribute reference syntax M.name (where M is any expression whose value is the module, and identifier name is the attribute name). For clarity, however, it's usually best to bind module attributes in the module body.

The import statement implicitly defines some module attributes as soon as it creates the module object, before the module's body executes. The _ _dict_ _ attribute is the dictionary object that the module uses as the namespace for its attributes. Unlike all other attributes of the module, _ _dict_ _ is not available to code in the module as a global variable. All other attributes in the module are entries in the module's _ _dict_ _, and they are available to code in the modules as global variables. Attribute _ _name_ _ is the module's name, and attribute _ _file_ _ is the filename from which the module was loaded, if any.

For any module object M, any object x, and any identifier string S (except _ _dict_ _), binding M.S=x is equivalent to binding M._ _dict_ _['S']=x. An attribute reference such as M.S is also substantially equivalent to M._ _dict_ _['S']. The only difference is that when 'S' is not a key in M._ _dict_ _, accessing M._ _dict_ _['S'] directly raises KeyError, while accessing M.S raises AttributeError instead. Module attributes are also available to all code in the module's body as global variables. In other words, within the module body, S used as a global variable is equivalent to M.S (i.e., M._ _dict_ _['S']) for both binding and reference.

7.1.1.3 Python built-ins

Python offers several built-in objects (covered in Chapter 8). All built-in objects are attributes of a preloaded module named _ _builtin_ _. When Python loads a module, the module automatically gets an extra attribute named _ _builtins_ _, which refers to either module _ _builtin_ _ or to _ _builtin_ _'s dictionary. Python may choose either, so don't rely on _ _builtins_ _. If you need to access module _ _builtin_ _ directly, use an import _ _builtin_ _ statement. Note the difference between the name of the attribute and the name of the module: the former has an extra s. When a global variable is not found in the current module, Python looks for the identifier in the current module's _ _builtins_ _ before raising NameError.

The lookup is the only mechanism that Python uses to let your code implicitly access built-ins. The built-ins' names are not reserved, nor are they hardwired in Python itself. Since the access mechanism is simple and documented, your own code can use the mechanism directly (in moderation, or your program's clarity and simplicity will suffer). Thus, you can add your own built-ins or substitute your functions for the normal built-in ones. You can restrict an untrusted module by controlling what built-ins the untrusted module sees (as covered in Chapter 13). The following example shows how you can wrap a built-in function with your own function (_ _import_ _ and reload are both covered later in this chapter):

# reload takes a module object; let's make it accept a string as well
import _ _builtin_ _
_reload = _ _builtin_ _.reload                   # save the original built-in
def reload(mod_or_name):
    if isinstance(mod_or_name, str):             # if argument is a string
        mod_or_name = _ _import_ _(mod_or_name)  # get the module instead
    return _reload(mod_or_name)                  # invoke the real built-in
_ _builtin_ _.reload = reload                # override built-in with wrapper
7.1.1.4 Module documentation strings

If the first statement in the module body is a string literal, the compiler binds that string as the module's documentation string attribute, named _ _doc_ _. Documentation strings are also called docstrings. See Section 4.10.3 for more information on docstrings.

7.1.1.5 Module-private variables

No variable of a module is really private. However, by convention, starting an identifier with a single underscore (_), such as _secret, indicates that the identifier is meant to be private. In other words, the leading underscore communicates to client-code programmers that they should not access the identifier directly.

Development environments and other tools rely on the leading-underscore naming convention to discern which attributes of a module are public (i.e., part of the module's interface) and which ones are private (i.e., to be used only within the module). It is good programming practice to distinguish between private and public attributes by starting the private ones with _, for clarity and to get maximum benefit from tools.

It is particularly important to respect the convention when you write client code that uses modules written by others. In other words, avoid using any attributes in such modules whose names start with _. Future releases of the modules will no doubt maintain their public interface, but are quite likely to change private implementation details.

7.1.2 The from Statement

Python's from statement lets you import specific attributes from a module into the current namespace. from has two syntax variants:

from modname import attrname [as varname][,...]
from modname import *

A from statement specifies a module name, followed by one or more attribute specifiers separated by commas. In the simplest and most common case, attrname is an identifier that names a variable that Python binds to the attribute of the same name in the module named modname. For example:

from MyModule import f

modname can also be a sequence of identifiers separated by dots (.) that names a module within a package, as covered later in this chapter.

When as varname is part of a from statement, Python binds the variable named varname to the attribute, but the module attribute from which the variable gets its value is attrname. For example:

from MyModule import f as foo

attrname and varname are always simple identifiers.

Code that is directly inside a module body (not in the body of a function or class) may use an asterisk (*) in a from statement:

from MyModule import *

The * requests that all attributes of module modname be bound as global variables in the importing module. When the module has an attribute named _ _all_ _, the attribute's value is the list of the attributes that are bound by this type of from statement. Otherwise, this type of from statement binds all attributes of modname except those beginning with underscores. Since from M import * may bind an arbitrary set of global variables, it can have unforeseen and undesired side effects, such as hiding built-ins and rebinding variables you still need. Thus, you should use the * form of from very sparingly and only from modules that are explicitly documented as supporting such usage.

In general, the import statement is a better choice than the from statement. I suggest you think of the from statement, and particularly from M import *, as conveniences meant only for occasional use in interactive Python sessions. If you always access module M with the statement import M, and always access M's attributes with explicit syntax M.A, your code will be slightly less concise, but far clearer and more readable. from is a good idea only for modules whose documentation explicitly specifies from support (such as module Tkinter, covered in Chapter 16). Another good use of from is to import specific modules from a package, as we'll discuss in Section 7.3 later in this chapter.

    Previous Section Next Section