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]