plugin system?
Jeff Epler
jepler at unpythonic.net
Sun Mar 30 20:43:07 EST 2003
Well, I'd make each plugin be a class (instance). You would actually name
the plugin with a dotted name, modname.classname (in configuration files,
or what have you).
For instance:
[Plugins]
PlugIn1 = spam_plugins.VikingChorus
# in file spam_plugins.py
class VikingChorus:
def __init__(self, app):
self.app = app
def sing_refrain(self, text):
self.app.display(", ".join(text * 4) + "!")
raise StopPropagating
In the code, you would instantiate the class with a helper function:
def get_plugin_factory(name):
# If you have packages (eg monty_python.spam.VikingChorus
# or spam.spam.spam.spam.baked-beans.spam) this won't work
# as written
m, f = name.split(".")
d = {}
exec "import m" in d
return eval(name, d)
...
# Actually create the plugin and put it on the list
factory = get_plugin_factory("spam_plugins.VikingChorus")
plugin = factory(app)
plugins.append(plugin)
If you have an event concept, you can now filter it through the plugins
(this is similar to an observer pattern):
class App:
...
def plugin_event(self, event, *args):
for p in self.plugins:
handler = getattr(p, event, None)
if handler is None: continue
try:
handler(*args)
except StopPropagating:
# The plugin says the event was completely handled
break
# And here's how you'd do it
app.plugin_event("sing_refrain", "spam")
A plugin could call back into app or access app's data members, etc by
storing a reference in its initializer. Or you could choose to pass 'app'
at every call.
There's a lot of stuff here, and I'd say it's well beyond "beginner"
technique. Of course, I've probably also left a bug in the above
since it's not quite a complete, runnable example... best of luck.
Jeff
More information about the Python-list
mailing list