Is this a good use of __metaclass__?

Michele Simionato michele.simionato at gmail.com
Mon May 8 05:14:02 EDT 2006


Answering to the title of your post, no, this is not a good use of
metaclasses.
Your problem seems a textbook example of multiple dispatch, so I
suggest
you to look at PEAK with has an implementation of multimethods/generic
functions. Notice that Guido seems to be intentioned to add support for
generic functions in future versions of Python, so that solution would
likely have the
blessing of the BDFL ;)
The problem you have with your metaclass version, is the infamous
metaclass
conflict. It can be solved by hand or automatically
(http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197) but it
is best
to avoid it altogether. Just use PEAK or an hand made dispatcher, like
for
instance this one:


class SimpleDispatcher(object): # this is on purpose not object
oriented
    """A dispatcher is a callable object that looks in a "namespace"
    for callable objects and calls them with the signature

    ``<dispatcher>(<callablename>, <dispatchtag>, <*args>, <**kw>)``

    The "namespace" can be a module, a class, a dictionary, or anything
    that responds to ``getattr`` or (alternatively) to ``__getitem__``.

    Here is an example of usage:

>>> call = SimpleDispatcher(globals())

>>> def manager_showpage():
...    return 'Manager'

>>> def member_showpage():
...     return 'Member'

>>> def anonymous_showpage():
...     return 'Anonymous'

>>> call('showpage', 'anonymous')
'Anonymous'
>>> call('showpage', 'manager')
'Manager'
>>> call('showpage', 'member')
'Member'
    """
    def __init__(self, ns):
        self._ns = ns
    def __call__(self, funcname, classname, *args, **kw):
        try:
            func = getattr(self._ns, '%s_%s' % (classname, funcname))
        except AttributeError:
            func = self._ns['%s_%s' % (classname, funcname)]
        return func(*args, **kw)

if __name__ == "__main__":
    import doctest; doctest.testmod()

BTW, the usual advice holds here: if you can find an workable solution
not involving
metaclasses and decorators, don't use them.

      Michele Simionato




More information about the Python-list mailing list