Is there a better way to have a minimal Python plugin mechanism than the following?
(This was inspired from this post.)
import sys
import pkgutil
import os.path
import plugins
pluginsPath = os.path.dirname(plugins.__file__)
pluginModules = [name for _, name, _ in pkgutil.iter_modules([pluginsPath])]
dictOfPlugins = {}
for plugin in pluginModules:
thePluginModuleName = "plugins."+plugin
result = __import__(thePluginModuleName)
dictOfPlugins[plugin] = sys.modules[thePluginModuleName]
(This does assume that all your plugins are in a directory called "plugins" and thus are modules in that package, and that that directory has a blank __init__.py file in it.)
If you wanted to look for a particular plugin, the name would be a key in the dictOfPlugins
, and the module object itself would be the value. Assuming you knew what the interface to your Python plugin modules would be, this would seem to do the job. Is there a better way to do this?
1 Answer 1
Check out how Django apps work:
- Plugins are genuine Python packages, so the standard tools can be used to install them
- Plugins that are actually used must be in the PYTHONPATH and listed (only the package name) in the configuration.
- There are scripts to help create, test, ... plugins
- The plugin structure is extensible in all possible ways.
- Plugins are reloaded when they change in development mode.
I'm not saying that you should use Django if you're not doing web development, but you can inspire your plugin system on it.
-
\$\begingroup\$ totally agree, this was very helpful suggestion. You can checkout the loading mechanism itself @ docs.djangoproject.com/en/1.11/_modules/django/utils/… \$\endgroup\$JL Peyret– JL Peyret2017年08月24日 20:36:54 +00:00Commented Aug 24, 2017 at 20:36
plugins.register()
method and call that after the plugin declaration. (e.g.plugins.register('pluginModuleName')
orplugins.register(pluginModule)
. Does that make sense? \$\endgroup\$