Best practices for dynamically loading plugins at startup

Jack Diederich jack at performancedrivers.com
Mon Sep 26 15:02:21 EDT 2005


On Sun, Sep 25, 2005 at 11:24:04PM +0200, Christoph Haas wrote:
> Dear coders...
> 
> I'm working on an application that is supposed to support "plugins".
> The idea is to use the plugins as packages like this:
> 
> Plugins/
>   __init__.py
>   Plugin1.py
>   Plugin2.py
>   Plugin3.py
> 
> When the application starts up I want to have these modules loaded
> dynamically. Users can put their own plugin modules into the
> Plugins/ directory and the application should know about it.
> 
> Each plugin is supposed to be a class derived from a general
> "Plugin" superclass. I just don't know how to 'register' every
> plugin. 

If you want every class that defines the Plugin class to be registered
a metaclass will get you there.  Here is one that I use.

class Register(type):
  """A tiny metaclass to help classes register themselves automagically"""
  def __init__(cls, name, bases, dict):
    if ('register' in dict): # initial dummy class
      setattr(cls, 'register', staticmethod(dict['register']))
    elif (getattr(cls, 'DO_NOT_REGISTER', 0)): # we don't want to register this non-concrete class
      delattr(cls, 'DO_NOT_REGISTER')
    elif (object not in bases):
      cls.register(name, cls)
    return

class Plugin(object):
  __metaclass__ = Register
  all_plugins = []
  def register(name, cls):
    all_plugins.append(cls)    
    return

Plugin.all_plugins will be a list of all the classes that inherit from Plugin
(and that don't have a DO_NOT_REGISTER attribute).

-jackdied



More information about the Python-list mailing list