Thursday, 9 July 2009

Dynamic Module Loading using Python

Suppose I have a number of supported database engines which I keep in a dictionary like so:

db_libs = {
space0: 'psycopg2.psycopg1',
space1: 'psycopg',
space2: 'MySQLdb', 3: 'sqlite3'
}


My user can then select the engine they prefer to use and I now want to import the appropriate library. I could, of course, do this...

if user_choice == 0:
spaceimport psycopg2.psycopg1
elif user_choice == 1:
spaceimport psycopg
...

Made even more verbose than it would be in any other language because of the absence of a switch statement in Python.

Clearly this is not a great solution. Everytime I add support for something new then I must write another elif clause - not cool! After I bit of playing around with eval, I got to...

Database = eval("__import__('{0}')".format(db_libs[user_choice]))

And after a little further investigation I also discovered the imp module:

from imp import find_module, load_module
fp, pathname, description = find_module(
db_libs[user_choice])
Database = load_module(
db_libs[user_choice], fp, pathname, description)

More code, but it feels a bit safer for those cases where the dynamic element is coming from the user more directly.

---
#EDIT (July 10th) - imp.find_module() doesn't seem to support the two part module name (e.g 'psycopg2.psycopg1') although it works for my other examples. The eval works fine even in this case.

No comments:

Post a Comment

LinkWithin

Related Posts Plugin for WordPress, Blogger...