Understanding Module Importing

When the Python interpreter processes the import statement, it calls the function_import_(name[, globals[, locals[, fromlist]]]), which in turn locates the module called name, retrieving its byte code so that a new module object can be created. The globals and locals parameters hold the global and local dictionaries so that_import_can determine the context in which the import is taking place. fromlist is a list of items to import from the module when the from x import y form of import is used.

Chapter 6 describes modules, packages, and the import statement.

The primary reason_import_exists in Python (as opposed to being accessible only via the Python/C API) is so that you can modify or track module imports. For example, the following code replaces the normal importer with a function that informs you of each module being loaded:

In This Chapter

Understanding module importing

Finding and loading modules with imp

Importing encrypted modules

Retrieving modules from a remote source ♦ ♦ ♦ ♦

oldimp = _import_ # Save a reference to the original def newimp(name, globals=None, locals=None, fromlist=None):

# Display info about the import request if not fromlist:

# Now call the original function return oldimp(name,globals,locals,fromlist)

_builtins_._import_ = newimp

After running the preceding code, you can see that import calls are indeed routed to the new function, including imports that other modules request on their own:

>>> import os :: import os >>> os = reload(os) :: import sys :: from nt import * :: from nt import _exit :: import ntpath :: import UserDict

Tip The knee module in the standard Python distribution is an example of replacing the built-in_import_function. It doesn't add new functionality, but it is useful

' for seeing how things work.

Another use of_import_is to modify the module before returning it to the caller.

For example, the following code adds a timestamp to each module, marking when it was originally loaded:

import sys, time oldimp = _import_

def newimp(name, globals=None, locals=None, fromlist=None): try:

mod = sys.modules[name] first_load = mod.first_load except (AttributeError, KeyError): first_load = time.time()

mod = oldimp(name,globals,locals,fromlist) mod.first_load = first_load return mod

_builtins_._import_ = newimp

The module maintains its original timestamp, even if reloaded:

>>> import md5 >>> md5.first_load 982444108.24399996 >>> md5 = reload(md5) >>> md5.first_load 982444108.24399996

Note Some modules will have already been loaded by the time your import hook is called, so they won't have a timestamp unless they are loaded again later.

Instead of completely replacing Python's import behavior, other modules let you replace or extend only parts of it. The following sections cover the imp and imputil modules.

Note The i hooks module is another way to modify module import behavior; it is currently used by rexec (restricted execution). New programs should avoid using i hooks, and use imp and imputi 1 instead.

0 0

Post a comment