If things look a little dusty around here, it's because I'm away on a mission for two years. I'll be back in August 2012, but in the mean time feel free to fork my projects on github.
Python Registrar
Jul 10, 2010
by Jared
http://jaredforsyth.com/media/projects/logo_.png

Here's a small library I've been playing around with: registrar. I often find myself writing meta decorators:

_reg = {}
def register(name):
     def meta(func):
          _reg[name] = func
          return func
     return meta

Or some such thing. And that solution is very often enough. But, for the times when you need a bit more control, I've created Registrar. The situation that prompted me to write this was within the confines of a class -- and the functions were being "registered" before they became bound...

Here's the registrar:

import types
class Registrar:
    def __init__(self, swallow=False):
        self.reg = {}
        self.swallow = swallow

    def register(self, *args, **kwds):
        def meta(func):
            self.add(func, args, kwds)
            if not self.swallow:
                return func
        return meta
    __call__ = register

    def add(self, func, args, kwds):
        self.reg[func] = (args, kwds)

    def bind(self, inst):
        res = {}
        for func, value in self.reg.iteritems():
            if callable(func):
                func = types.MethodType(func, inst, inst.__class__)
            res[func] = value
        return res

And a subclass, if you want a name (or other id) associated w/ your function

class NamedRegistrar(Registrar):
    def add(self, func, args, kwds):
        if not args:
            raise TypeError('at least one positional argument required (0 given)')
        self.reg[args[0]] = (func, args[1:], kwds)
        return func

    def bind(self, inst):
        res = {}
        for name, value in self.reg.iteritems():
            value = list(value)
            if callable(value[0]):
                value[0] = types.MethodType(value[0], inst, inst.__class__)
            res[name] = list(value)
        return res

But of course all you want is an honest application. So here's an example using event handling:

class Spam:
    def __init__(self):
        self.events = self._events.bind(self)

        # or
        self.shop = Shoppe()
        for event, value in self._events.bind(self):
            self.show.addEventHandler(event, value[0], **value[2])

    ## setup events
    _events = NamedRegistrar()

    @_events('cheese', bubble=False)
    def onCheese(self, baz):
        pass

    @_events('eggs')
    def onEggs(self, baz):
        return 'no eggs. cheese.'

Has anyone done this before? Am a solving a problem that doesn't exist? Tell me in the comments.

blog comments powered by Disqus