Dynamic loading of python module
Sometimes ago, a friend of mine recommended me to have a look at python language. Very quickly I got hooked by how easy and developer friendly is that language. The language is straight forward and the number of loadable modules is absolutely amazing.
So we go on our python serie with a small piece of code that could be useful for python developers who want to dynamically load ‘packages’ (called on the fly import)
The problem:
Being able to load dynamically (at runtime) some packages to extend your code.
Solution:
in all this tutorial, we will use the so unfamous __import__ python builtin.
First, let’s create a package that we can “autoload”.
In fact, it will be a regular (and respectful) package like there is tons for python. A package is a piece of code that realize a specific task. It has also a well defined structure.
The structure of the package will be as follow :
package_name:
-> __init__.py
-> mymodule.py
First the file __init__.py is a mandatory file that tells that your directory is in fact a package. The file mymodule.py is a regular python script that contain the class that we want to use.
Here is the code of these two file.
The first file (__init__.py)
""" This modules should keep help use in the future """ __author__ = "sebastien requiem (kolios.dk)" __license__ = "No License" __version__ = "0.0.1" from .mymodule import MyModule def instantiate(): return MyModule()
and the python module code itself (mymodule.py)
import os import logging class MyModule: """ This class is a very cool and helpful class """ def __init__(self): print "We are initializing MyModule.. w00t !" def mymethod(self): """ Simple routines """ print "mymethod has been called"
As you can see, there is no fancy code here. Just note that the __init__.py script contain a function call instantiate and that return an instance of the class that we need.
Now let’s see how we can make use of that module.
The following piece of code is meant to be used in a production environment but gives you a clear view on how to load dynamically.
import sys
#first we make sure that the current path is in our path.
sys.path.append(0, '.')
# we need a placeholder for all our modules
modules ={}
# we define a list of modules we want to load
module_list = []
module_list.append('mymodule')
for module_name in module_list:
try:
modules[module_name] = __import__(module_name)
print "Successfully loaded module : %s" % module_name
except ImportError, e:
print e
print "can't load %s module" % module_name)
That’s is folks, as simple as that. Let me know in the comments all the troubles you can have with that piece of code. As I am not a python expert, let me know any improvements and ideas you can have regarding this subject.
For those who want to unload any module, you should be able to do it by deleting the key in sys.modules but I must admit that I haven’t been able to notice any memory improvement after having released any modules. Does that really works ?
See ya !
references:
- the __import__ python function : http://docs.python.org/library/functions.html#__import__
- Python package structure : http://docs.python.org/tutorial/modules.html
