Plugin Framework

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class PluginMount(type):
    def __init__(cls, name, bases, attrs):
        if not hasattr(cls, 'plugins'):
            # This branch only executes when processing the mount point itself.
            # So, since this is a new plugin type, not an implementation, this
            # class shouldn't be registered as a plugin. Instead, it sets up a
            # list where plugins can be registered later.
            cls.plugins = []
        else:
            # This must be a plugin implementation, which should be registered.
            # Simply appending it to the list is all that's needed to keep
            # track of it later.
            cls.plugins.append(cls)

More like this

  1. HTTP (basic) auth enabled (new-style) syndication framework feed class by hupf 1 year, 5 months ago
  2. Method Caching by bryanhelmig 10 months, 3 weeks ago
  3. Using descriptors for lazy attribute caching by djypsy 4 years, 9 months ago
  4. Passing values to a method from a template by miracle2k 4 years, 2 months ago
  5. integrated jinja2 which could use generic view ,my djangojinja2.py by jasongreen 2 years, 4 months ago

Comments

jezdez (on January 22, 2009):

This is just unbelievable awesome. Great snippet and weblog post!

#

mattjvincent (on August 26, 2010):

Help...

I received this error:

TypeError: unbound method perform() must be called with Insert instance as first argument (got nothing instead)

Here is the code....

class PluginMount(type):
    def __init__(cls, name, bases, attrs):
        if not hasattr(cls, 'plugins'):
            cls.plugins = []
        else:
            cls.plugins.append(cls)

class ActionProvider(object):
    __metaclass__ = PluginMount

class Insert(ActionProvider):
    def perform(self):
        print 'Insert'

class Update(ActionProvider):
    def perform(self):
        print 'Update'

if __name__ == '__main__':
    for action in ActionProvider.plugins:
        action.perform()

#

ffsffd (on April 27, 2011):

This is a little late, but just informational for everyone else.

The poster above me encountered the error because action (which is a class), is not being instantiated first.

So the fix is: if name == 'main': for action in ActionProvider.plugins: action().perform()

Really simple. :) And this idea really rocks.

#

ffsffd (on April 27, 2011):

Oops, here's the code again, correctly formatted.

if __name__ == '__main__':
    for action in ActionProvider.plugins:
        action().perform()

#

(Forgotten your password?)