1

My program is broken down into two parts: the engine, which deals with user interface and other "main program" stuff, and a set of plugins, which provide methods to deal with specific input.

Each plugin is written in its own module, and provides a function that will allow me to send and retrieve data to and from the plugin.

The name of this function is the same across all plugins, so all I need is to determine which one to call and then the plugin will handle the rest.

I've placed all of the plugins in a sub-folder, wrote an __ init__.py that imports each plugin, and then I import the folder (I think it's called a package?)

Anyways currently I explicitly tell it what to import (which is basically "import this", "import that"). Is there a way for me to write it so that it will import everything in that folder that is a plug-in so that I can add additional plugins without having to edit the init file?

MxLDevs
  • 19,048
  • 36
  • 123
  • 194

2 Answers2

2

Here is the code I use to do this:

def _loadPackagePlugins(package):
  "Load plugins from a specified package."
  ppath = package.__path__
  pname = package.__name__ + "."
  for importer, modname, ispkg in pkgutil.iter_modules(ppath, pname):
    module = __import__(modname, fromlist = "dummy")

The main difference from Jakob's answer is that it uses pkgutil.iter_modules instead of os.listdir. I used to use os.listdir and changed to doing it this way, but I don't remember why. It might have been that os.listdir failed when I packaged my app with py2exe and py2app.

new name
  • 15,861
  • 19
  • 68
  • 114
1

You could always have a dict called plugins, use __import__ to import the modules and store them that way.

e.g.

plugins = {}
for plugin in os.listdir('plugins'):
    plugin = plugin.split()[0]
    plugins[plugin] = __import__(plugin)

This is assuming that every plugin is a single file. Personally I would go with something that looks in each folder for a __run__.py file, like a __init__.py in a package it would indicate a plugin, that code would look more like something like this

for root, dirs, files in os.walk('.'):
    for dir in dirs:
        if "__run__.py" in os.listdir(os.path.join(root, dir)):
            plugins[dir] = __import__(dir)

Code written without testing. YMMV

Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91
  • Much more flexible than having a single folder, or hardcoding multiple folder names. Good idea. – MxLDevs Jun 29 '11 at 22:25