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 ElementTreeAlternatively, 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 ElementTreeImporting 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 # restoreIf 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]