For some reason (a database abstraction layer that would call a specific engine to do the actual work, if you must know) I needed to find a way to dynamically load modules and classes in Python. In other words, I needed code like this:
import db dbObj = db.DB(type='mysql', someparameters)
to return an instantiation of the DB class in the package db.engines.mysql.
After reading through the documentation and some Googling, I figured out how to do it. Let’s say we have the following files:
In db/__init__.py :
class DB(object):
__init__(self, dbtype, config):
module_name = 'db.engines.' + dbtype
# before python 2.5, __import__ had no named parameters. the non-empty list (fromlist) ensures we
# actually get the mysql engine object, not the db object
module_obj = __import__(module_name, globals(), locals(), [1])
class_obj = getattr(module_obj, 'DBEngine')
dbobject = class_obj(config)
self.dbobject = dbobject
# do whatever else you need to do to initialize a generic DB object
And in db/engines/mysql.py :
class DBEngine(object):
def __init__(self, config):
# do whatever you need to do to initialize a mysql db engine object
pass
In other words, you need to use the __import__ function to dynamically load the module you’re after (in this case db.engines.mysql.py) and then the getattr function to dynamically load a specific class from that module. Easy as pie, actually.