__import__ confusion
Steven Taschuk
staschuk at telusplanet.net
Wed Feb 26 01:13:13 EST 2003
Quoth Leazen:
> I'm trying to load modules dinamically. All modules which define a
> class (Plugin) should be imported and an object of the class within them
> created, do you think using __import__ is the way to go or that I should
> keep looking?
> Thanks again, first time doing this kind of thing.
Hm. Never done this sort of thing, but here's my first
impressions, for what they're worth:
I assume you've got a plugins directory somewhere that your app
knows about, and you want to spin through all the *.py files in
that directory, loading each, and instantiating each module's
Plugin class, if it defines one. Is this correct?
If so, I'm not sure __import__ is best. For one thing, I think
it'll go wandering off on sys.path looking for the specified
module; but you already know where the file is. The facilities
provided by the imp module might serve better.
Here's a quicky illustration. (I hope those more familiar than I
with this subject will offer comments.)
Two trivial plugin files:
# plugin1.py
class Plugin(object):
def __init__(self):
print 'plugin1 instantiated'
self.name = "I'm plugin1!"
# plugin2.py
class Plugin(object):
def __init__(self):
print 'plugin2 instantiated'
self.name = "I'm plugin2!"
And a script which loads them:
# loader.py
import imp
import os
PLUGIN_DIR = '.'
def getplugins():
plugins = []
for file in os.listdir(PLUGIN_DIR):
if file.endswith('.py'):
modulename = file[:-3]
try:
file, filename, description = imp.find_module(
modulename, [PLUGIN_DIR])
pluginmodule = imp.load_module(modulename,
file, filename, description)
if hasattr(pluginmodule, 'Plugin'):
print 'Instantiating plugin from %s' % pluginmodule
try:
plugins.append(pluginmodule.Plugin())
except Exception, e:
print 'Urk! %s' % e
else:
print 'No plugin in %s' % pluginmodule
finally:
if file:
file.close()
return plugins
if __name__ == '__main__':
plugins = getplugins()
for plugin in plugins:
print plugin.name
Result:
$ python loader.py
Instantiating plugin from <module 'plugin1' from './plugin1.pyc'>
plugin1 instantiated
Instantiating plugin from <module 'plugin2' from './plugin2.pyc'>
plugin2 instantiated
No plugin in <module 'loader' from './loader.pyc'>
I'm plugin1!
I'm plugin2!
Seems to work, anyway.
Some caveats:
- The loader should look for *.pyc and *.pyo files too. Maybe even
*.so files.
- The documentation says that imp.load_module() will do a reload if
the module has already been loaded; this might not be desirable.
I'm not sure how to prevent it, short of spinning through
sys.modules.
- The error handling is clumsy and probably wrong.
- There's no support for package structures in the plugin directory.
--
Steven Taschuk staschuk at telusplanet.net
"Its force is immeasurable. Even Computer cannot determine it."
-- _Space: 1999_ episode "Black Sun"
More information about the Python-list
mailing list