[EMAIL PROTECTED] wrote: > Hi, > > I am currently using the Cmd module for a mixed cli+gui application. I > am starting to refactor my code and it would be highly desirable if > many commands could be built as simple plugins. > > My idea was: > - Load a list of plugin names (i.e. from the config file, or from the > plugins directory) > - Import all plugins found dynamically: > and this is easy, since I can do, for example: > > PLUGIN_NAMES=['foo', 'bar'] > PLUGIN_MODULES = map(__import__, PLUGIN_NAMES) > PLUGINS = [item.Commands for item in PLUGIN_MODULES] > > Now, what I have to do is to define my command line class. This is > usually done by subclassing cmd.Cmd: > > class MyCli(cmd.Cmd): > .... > > Now I want to add the commands defined in foo.Commands and > bar.Commands. foo.Commands contains the functions corresponding to the > new commands this way: > #foo.py > class Commands > > def do_this(self,args): > ... > def do_that(self,args): > ... > > I've seen I can do it by explicitely import them and using multiple > inheritance: > > class MyCli(cmd.Cmd , foo.Commands, bar.Commands) > .... > > so that do_this and do_that are now methods of a Cmd command line. > > Now: > - how can I instead have MyCli inherit from a dynamic list of modules? > - is there a better way than using multiple inheritance to plug-in > dynamically commands in a Cmd command line?
Your plugins could define plain functions with names starting with do_. Then you can create an empty subclass of cmd.Cmd and just plug in the imported commands: In [1]: import cmd In [3]: def do_this(self, arg): print 'This', arg ...: In [4]: def do_that(self, arg): print 'That', arg ...: In [8]: class MyCmd(cmd.Cmd): pass ...: In [9]: MyCmd.do_this = do_this In [10]: MyCmd.do_that = do_that In [11]: c=MyCmd() In [12]: c.cmdloop() (Cmd) help Undocumented commands: ====================== help that this (Cmd) that That In your code you could use introspection to locate the plugin commands, something like PLUGIN_MODULES = map(__import__, PLUGIN_NAMES) for module in PLUGIN_MODULES: for name in dir(module): if name.startswith('do_'): setattr(MyCmd, name, getattr(module, name)) If the plugin module defines a list of commands then use that instead of dir(module). Kent -- http://mail.python.org/mailman/listinfo/python-list