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