The Question :
565 people think this question is useful
I’m writing a Python application that takes as a command as an argument, for example:
$ python myapp.py command1
I want the application to be extensible, that is, to be able to add new modules that implement new commands without having to change the main application source. The tree looks something like:
So I want the application to find the available command modules at runtime and execute the appropriate one.
Python defines an __import__ function, which takes a string for a module name:
__import__(name, globals=None, locals=None, fromlist=(), level=0)
The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name.
So currently I have something like:
command = sys.argv
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
# Display error message
This works just fine, I’m just wondering if there is possibly a more idiomatic way to accomplish what we are doing with this code.
Note that I specifically don’t want to get in to using eggs or extension points. This is not an open-source project and I don’t expect there to be “plugins”. The point is to simplify the main application code and remove the need to modify it each time a new command module is added.
The Question Comments :
The Answer 1
334 people think this answer is useful
With Python older than 2.7/3.1, that’s pretty much how you do it.
For newer versions, see
importlib.import_module for Python 2 and and Python 3.
You can use
exec if you want to as well.
__import__ you can import a list of modules by doing this:
>>> moduleNames = ['sys', 'os', 're', 'unittest']
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)
Ripped straight from Dive Into Python.
The Answer 2
327 people think this answer is useful
The recommended way for Python 2.7 and 3.1 and later is to use
Import a module. The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module(‘..mod’, ‘pkg.subpkg’) will import pkg.mod).
my_module = importlib.import_module('os.path')
The Answer 3
131 people think this answer is useful
Note: imp is deprecated since Python 3.4 in favor of importlib
As mentioned the imp module provides you loading functions:
I’ve used these before to perform something similar.
In my case I defined a specific class with defined methods that were required.
Once I loaded the module I would check if the class was in the module, and then create an instance of that class, something like this:
class_inst = None
expected_class = 'MyClass'
mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1])
if file_ext.lower() == '.py':
py_mod = imp.load_source(mod_name, filepath)
elif file_ext.lower() == '.pyc':
py_mod = imp.load_compiled(mod_name, filepath)
if hasattr(py_mod, expected_class):
class_inst = getattr(py_mod, expected_class)()
The Answer 4
19 people think this answer is useful
Nowadays you should use importlib.
Import a source file
The docs actually provide a recipe for that, and it goes like:
file_path = 'pluginX.py'
module_name = 'pluginX'
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
# check if it's all there..
This way you can access the members (e.g, a function “
hello“) from your module
pluginX.py — in this snippet being called
module — under its namespace; E.g,
If you want to import the members (e.g, “
hello“) you can include
pluginX in the in-memory list of modules:
sys.modules[module_name] = module
from pluginX import hello
Import a package
Importing a package (e.g.,
pluginX/__init__.py) under your current dir is actually straightforward:
pkg = importlib.import_module('pluginX')
# check if it's all there..
The Answer 5
17 people think this answer is useful
Use the imp module, or the more direct
The Answer 6
10 people think this answer is useful
If you want it in your locals:
>>> mod = 'sys'
>>> locals()['my_module'] = __import__(mod)
'2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Intel)]'
same would work with
The Answer 7
9 people think this answer is useful
You can use
exec("import myapp.commands.%s" % command)
The Answer 8
2 people think this answer is useful
Similar as @monkut ‘s solution but reusable and error tolerant described here http://stamat.wordpress.com/dynamic-module-import-in-python/:
def importFromURI(uri, absl):
mod = None
if not absl:
uri = os.path.normpath(os.path.join(os.path.dirname(__file__), uri))
path, fname = os.path.split(uri)
mname, ext = os.path.splitext(fname)
return imp.load_compiled(mname, uri)
return imp.load_source(mname, uri)
The Answer 9
0 people think this answer is useful
The below piece worked for me:
>>>fp, pathname, description = imp.find_module("/home/test_module");
>>>test_module = imp.load_module("test_module", fp, pathname, description);
if you want to import in shell-script:
python -c '<above entire code in one line>'
The Answer 10
-2 people think this answer is useful
For example, my module names are like
month = 'feb'
exec 'from %s_module import *'%(month)
The Answer 11
-8 people think this answer is useful
The following worked for me:
import sys, glob
fl = glob.glob('modus/*.py')
modulist = 
for i in range(len(fl)):
fl[i] = fl[i].split('/')
fl[i] = fl[i][0:(len(fl[i])-3)]
It loads modules from the folder ‘modus’. The modules have a single class with the same name as the module name. E.g. the file modus/modu1.py contains:
The result is a list of dynamically loaded classes “adapters”.