Some Notes on Importing Modules by Name

October 2006 | Fredrik Lundh

Python’s import statement makes it easy to import external modules, and bind them to names in your local namespace:

# bind local "module" name to the loaded module
import module

# bind local names to all names in the loaded module
from module import *

Importing Modules by Name #

If you have a module name in a string, you can use the built-in __import__ function to import it:

    module = __import__("module")

Note that you have to assign the module object to a variable yourself. This allows you to rename the module on the way in:

    dbapi = __import__(get_database_driver())

Importing modules from packages is a bit trickier; __import__ does the full import, but it returns the top-level package, not the actual module. To get the module, you can use a simple getattr loop:

 
    def my_import(name):
        m = __import__(name)
        for n in name.split(".")[1:]:
            m = getattr(m, n)
        return m

    m = __import__("xml.etree.ElementTree") # returns xml
    m = my_import("xml.etree.ElementTree") # returns ElementTree

Alternatively, you can fetch the module from the sys.modules dictionary after the import:

 
    import sys

    def my_import(name):
        __import__(name)
        return sys.modules[name]

    m = my_import("xml.etree.ElementTree") # returns ElementTree

Importing Modules by Filename #

To import a module from a given filename, you can temporarily extend the path:

    filename = "directory/module.py"

    directory, module_name = os.path.split(filename)
    module_name = os.path.splitext(module_name)[0]

    path = list(sys.path)
    sys.path.insert(0, directory)
    try:
        module = __import__(module_name)
    finally:
        sys.path[:] = path # restore

If you just want to load code from a script, instead of importing it, execfile is often a better choice. This function lets you execute external scripts, and collect the result in a namespace dictionary.

    namespace = {}
    execfile("directory/module.py", namespace)

To import all names from an imported module or a loaded namespace into your own module, similar to from-import-*, you can do:

    globals().update(vars(module))

    globals().update(namespace)

To fully emulate from-import, you need to check for an __all__ attribute, and if that’s not present, filter out anything that starts with an underscore:

 
    all_names = namespace.get("__all__")
    if all_names is None:
        all_names = (key for key in namespace where key[0] != "_")
    my_namespace = globals()
    for name in all_names:
        my_namespace[name] = namespace[name]

A Django site. rendered by a django application. hosted by webfaction.