A Python Plugin Framework
Table of Contents
1 A Framework with metaclass
- Example code
# main.py
import os, sys from plugin import * if __name__ == "__main__": # test PluginMgr print pluginmgr.get_plugins()
# plugin.py
import os,sys class _Plugin(object): class __metaclass__(type): def __init__(cls, name, bases, attrs): if not hasattr(cls, 'plugins'): cls.plugins = {} print "in if:" print cls else: print "%s %s" % (attrs['name'],name) print cls cls.plugins[attrs['name']] = cls print cls.plugins def show_plugins(cls): for kls in cls.plugins.values(): print kls def get_plugins(cls): return cls.plugins class PluginMgr(object): plugin_dirs = {} # make the manager class as singleton _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(PluginMgr, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self): self.plugin_dir="/home/yannik/work/plugin_python/plugins/" self.plugin_dirs[self.plugin_dir] = False def _load_all(self): for (pdir, loaded) in self.plugin_dirs.iteritems(): if loaded: continue sys.path.insert(0, pdir) for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]: if mod and mod != '__init__': if mod in sys.modules: print "Module %s already exists, skip" % mod else: try: pymod = __import__(mod) self.plugin_dirs[pdir] = True print "Plugin module %s:%s imported"\ % (mod, pymod.__file__) except ImportError, e: print 'Loading failed, skip plugin %s/%s'\ % (os.path.basename(pdir), mod) del(sys.path[0]) def get_plugins(self): """ the return value is dict of name:class pairs """ self._load_all() return _Plugin.get_plugins() pluginmgr = PluginMgr()
# plugin1.py
import os, sys from plugin import _Plugin class Plugin_1(_Plugin): name = 'Plugin1' def get_name(self): return name
# plugin2.py
import os, sys from plugin import _Plugin class Plugin_2(_Plugin): name = 'Plugin2' def get_name(self): return name
- The directory tree
. ├── main.py ├── plugin.py ├── plugin.pyc └── plugins ├── plugin1.py ├── plugin1.pyc ├── plugin2.py └── plugin2.pyc